[结论题] [dp] [单调队列优化] P2300 合并神犇
posted on 2024-03-11 05:40:12 | under | source
前言:周六和 lsy 找到了 P2300 合并神犇这道题,做完后才发现很像 P5665 划分,这两题的解的合法性定义都是完全一样的,只是答案不同。
结论部分
上数学课时手推的,如有不严谨之处请指出。
首先定义 \(f_i\) 表示前 \(i\) 个数的最小合并次数,\(lst_i\) 所有情况下合并后结尾元素最小值。
- 引理: \(\forall i\in [2,n],0\le f_i-f_{i-1}\le 1\)。
证明:对于上界,\(f_i\) 可以由 \(f_{i-1}+1\) 得到,即将 \(lst_{i-1}\) 与 \(a_i\) 合并。
再证下界。假如 \(lst_i=a_i\),则 \(f_{i-1}\) 可以由 \(f_i-1\) 得到,去掉 \(a_i\) 即可。反之,将 \(a_i\) 去掉,再将末尾元素与倒数第二个元素合并,\(f_{i-1}=f_i-1+1=f_i\)。证毕。
- 结论:\(a_1...a_i\) 的答案必定满足 \(lst_i\) 最小。
证明:反证法。设 \(f_i\) 取最小值时,结尾元素(合并后)\(>lst_i\)。令该情况下结尾元素由 \(a_j...a_i\) 合并得到,\(lst_i\) 由 \(a_k...a_i\) 合并得到。由于 \(\forall a_i>0\),所以 \(j<k\)。
同时,在此假设下 \(lst_i\) 对应的答案 \(ans\prime>f_i\)。我们知道 \(f_i=f_j+i-j-1\),\(ans\prime=f_k+i-k-1\),代入上式并化简得 \(f_k-f_j>k-j\)。由引理知 \(i\) 每增长 \(1\),\(f_i\) 至多增长 \(1\),所以 \(f_k-f_j\le k-j\)。矛盾,假设不成立,故原结论正确,证毕。
dp 部分
维护 \(f_i\)、\(lst_i\),定义与上面的相同。暴力转移是 \(O(n^2)\) 的,需要优化。
观察暴力转移代码,\(s\) 是 \(a\) 前缀和:
for(int j = 0; j <= i - 1; ++j){
if(lst[j] <= s[i] - s[j] && f[j] + (i - j - 1) <= f[i]){
f[i] = f[j] + (i - j - 1);
lst[i] = min(lst[i], s[i] - s[j]);
}
}
由于转移不存在 \(F(i)\times G(j)\) 的形式,故考虑单调队列优化。
易发现 \(s\) 单调递增,于是对于决策的限制是不断放宽的。
还可发现对于 \(j<k\),必有 \(f_j+(i-j-1)\ge f_k+(i-k-1)\)。于是最优决策点 \(j\) 不会左移。
然后要使 \(s_i-s_j\) 最小,即 \(j\) 最大。可以想到维护下标递增、\(lst\) 递增的单调队列。每次从头开始找到最后一个满足 \(lst_k+s_k\le s_i\) 的 \(k\) 作为最优决策点,\(k\) 之前的全都踢出(决策点不左移);然后从队尾开始,将 \(lst_p\ge lst_i\) 的 \(p\) 全部踢出,将 \(i\) 入队(\(i\) 在答案上比 \(p\) 更优、也更容易满足限制)。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 5;
int n, a[N], f[N], lst[N], q[N], l, r;
signed main(){
cin >> n;
for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]), a[i] += a[i - 1];
q[l = r = 1] = 0;
for(int i = 1; i <= n; ++i){
while(l + 1 <= r && lst[q[l + 1]] + a[q[l + 1]] <= a[i]) ++l;
f[i] = f[q[l]] + (i - q[l] - 1), lst[i] = a[i] - a[q[l]];
while(l <= r && lst[q[r]] + a[q[r]] >= lst[i] + a[i]) --r;
q[++r] = i;
}
cout << f[n];
return 0;
}
总结
这两题都先从性质入手,P2300 通过数学推理得出结论,P5665 通过贪心感性猜出性质,并通过打表得到一定验证。使得状态被优化至 \(O(n)\) 的级别。

浙公网安备 33010602011771号