[决策单调性] P4072 [SDOI2016] 征途
posted on 2024-05-21 12:56:57 | under | source
\(s_i\) 是前缀和,\(vs_i\) 是划分每一段的权值和。
先化式子:\(v m^2=p^2+m\sum{vs_i}^2-2p\sum vs_i\)。
只考虑后面两项,易得转移:\(f_{i,j}=\max\limits_{0\le p\le i}(f_{p,j-1}+w(p,i))\)。
其中 \(w(p,i)=m(s_i-s_p)^2-2s_n(s_i-s_p)\)。它满足四边形不等式,\(f\) 可以决策单调性优化。
证明思路就是证 \(w_1(x,y)=(s_y-s_x)^2\) 和 \(w_2(x,y)=s_x-s_y\) 都满足四边形不等式,那么它们的线性组合也满足条件。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e3 + 5;
int n, m, a[N], f[N][N];
inline int w(int x, int y) {return m * (a[y] - a[x]) * (a[y] - a[x]) - 2 * a[n] * (a[y] - a[x]);}
inline void calc(int l, int r, int kl, int kr, int j){
if(l > r || kl > kr) return ;
int k = kl, mid = l + r >> 1;
for(int p = kl; p <= min(mid, kr); ++p){
int W = f[p][j - 1] + w(p, mid);
if(W <= f[mid][j]) f[mid][j] = W, k = p;
}
calc(l, mid - 1, kl, k, j), calc(mid + 1, r, k, kr, j);
}
signed main(){
cin >> n >> m;
for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]), a[i] += a[i - 1];
memset(f, 0x3f, sizeof f), f[0][0] = 0;
for(int j = 1; j <= n; ++j) calc(1, n, 0, n, j);
cout << f[n][m] + a[n] * a[n];
return 0;
}

浙公网安备 33010602011771号