题解:P4767 [IOI2000] 邮局 加强版
xiezheyuan · · 题解
摘要:本文将介绍一种 决策单调性分治 做法。
首先有一个 dp,设
其中
观察这个转移式,可以按照
由于
具体来说,假设现在分治到区间
时间复杂度
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 3e3 + 5;
int n, m, a[N], f[N], g[N], w[N][N];
void solve(int l, int r, int L, int R){
if(l > r) return;
int mid = (l + r) >> 1, s = L;
auto wgt = [&](int k, int i){ return g[k] + w[k + 1][i]; };
for(int i=L;i<=min(R, mid - 1);i++){
if(wgt(i, mid) < wgt(s, mid)) s = i;
}
f[mid] = wgt(s, mid);
solve(l, mid - 1, L, s);
solve(mid + 1, r, s, R);
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n >> m;
for(int i=1;i<=n;i++) cin >> a[i];
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
w[i][j]=w[i][j-1]+a[j]-a[(i+j)>>1];
}
}
for(int i=1;i<=n;i++) f[i] = w[1][i];
for(int i=2;i<=m;i++){
copy(f + 1, f + n + 1, g + 1);
solve(1, n, 1, n);
}
cout << f[n] << '\n';
return 0;
}
// Written by xiezheyuan