[bzoj3675]序列分割

可以发现分割的顺序并不会影响答案,也就是一个划分的问题
dp,用f[i][j]表示前i个数划分为j段的答案,那么方程是$f[i][j]=max(f[k][j-1]+(S[i]-S[k])*(S[n]-S[i])$,滚动+斜率优化即可

 1 #include
 2 using namespace std;
 3 #define N 200005
 4 #define y(i) (g[i]-a[i]*a[n])
 5 int n,k,x,l,r,q[N];
 6 long long a[N],g[N],f[N];
 7 double xl(int i,int j){
 8     return 1.0*(y(i)-y(j))/(a[i]-a[j]);
 9 }
10 int main(){
11     scanf("%d%d",&n,&k);
12     for(int i=1;i<=n;i++){
13         scanf("%d",&x);
14         a[i]=a[i-1]+x;
15     }
16     for(int i=0;i<=k;i++){
17         l=r=1;
18         for(int j=1;j<=n;j++){
19             while ((l1])>-a[j]))l++;
20             x=q[l];
21             f[j]=g[x]+(a[j]-a[x])*(a[n]-a[j]);
22             while ((l1],q[r]);
23             if (a[j]!=a[j-1])q[++r]=j;
24         }
25         memcpy(g,f,sizeof(f));
26     }
27     printf("%lld",f[n]);
28 }
View Code

 

你可能感兴趣的:([bzoj3675]序列分割)