AtCoder瞎做第二弹

ARC 067

F - Yakiniku Restaurants

题意

\(n\) 家饭店,\(m\) 张餐票,第 \(i\) 家和第 \(i+1\) 家饭店之间的距离是 \(A_i\) ,在第 \(i\) 家饭店用掉第 \(j\) 张餐票会获得 \(B_{i, j}\) 的好感度,可以从任意一个饭店出发,求好感度减经过的距离和的差的最大值。

\(2 \le n \le 5000, 1 \le m \le 200, 1 \le A_{i, j}, B_{i, j} \le 10^9\)

题解

做题千万条,看题第一条。

显然我们不会走回头路,那么每次我们选择的一定是一段连续区间 \([l, r]\)

考虑每个 \(B_{i, j}\) 对于哪些区间有贡献,找到左右第一个比它的 \(B_{x, j}, B_{y, j} \ge B_{i, j}\) ,那么它贡献的区间其实就是 \(l \in (x, i], r \in [i, y)\)

我们利用单调栈算出端点,然后矩形加利用二维差分实现即可。

\(\mathcal O(n^2 + nm)\)

代码

Submission #5013272

ARC 068

F - Solitaire

题意

有一个双端队列。

首先将 \(n\) 个数 \(1\sim n\) 从小到大任意前后地添入队列。然后任意前后地弹出队列,求最后弹出来的排列中,第 \(k\) 个数为 \(1\) 的排列有多少种。

\(1 \le k \le n \le 2000\)

题解

一开始添完的序列性质显然是将 \(1\) 分成两段,左边递减,右边递增。

由于构造合法序列是左右弹元素,那么性质就比较好推了。

  • \(k\) 个数为 \(1\)
  • \(k - 1\) 个数可拆分为至多两个下降子序列;
  • \(k - 1\) 个数的最小值一定大于后 \(n - k\) 个数的最大值。

先考虑最后 \(n - k\) 个数的方案,如果我们确定了前 \(k\) 个数,那么剩下的 \(n - k\) 个数是由一个单调队列弹出来的,除了最后一次只能弹一个,别的每次都有两种选择,所以方案是 \(2^{\max(0, n - k - 1)}\)

然后前面拆分成至多两个下降子序列,这个和 这道题 是一样的。

我们现在只需要满足第一个限制了,由于第 \(k\) 个数是需要最小值,用至多选 \(k\) 个和 \(k - 1\) 个差分一下即可。

然后利用之前那个题的组合数结论就可以做到 \(\mathcal O(n)\) 了。

其实那个组合数有个更优美的形式,也就是 \(\displaystyle {n + m \choose m} - {n + m \choose m - 1}\) ,意义明显许多。

代码

Submission #5016238

猜你喜欢

转载自www.cnblogs.com/zjp-shadow/p/10730876.html