3675: [Apio2014]序列分割 斜率优化DP

来源:互联网 发布:2016年护肤品数据报告 编辑:程序博客网 时间:2024/05/22 00:07

我们可以发现,如果切的位置确定,那么切的顺序是没有影响的。
因此,化无序为有序
那么我们可以DP一下,f[I][j]表示前I个切j刀的最大值,那么转移方程显然。。f[I][j]=max(f[k][j-1]+sum[k]*(sum[I]-sum[k]))。
然后化简一下。。
过程在本子上。。就不码了QAQ。。典型的斜率优化。

APIO2014的题似乎比较良心?QAQ

注意:
尽量避免除法,化作乘法运算。

#include<bits/stdc++.h>#define ll long longusing namespace std;int n,k,l,r,now,last;ll f[100005][2],y[100005][2],sum[100005];int q[100005],ans[100005];inline ll read(){    ll a=0,f=1; char c=getchar();    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}    return a*f;}int main(){    n=read(); k=read();    for (int i=1;i<=n;i++) sum[i]=read()+sum[i-1],y[i][0]=(ll)sum[i]*sum[i];    for (int j=1;j<=k;j++)    {        now=j&1; last=now^1;        l=1; r=1; q[1]=j;        for (int i=j+1;i<=n;i++)        {            while (l<r&&(y[q[l]][last]-y[q[l+1]][last])>=sum[i]*(sum[q[l]]-sum[q[l+1]])) l++;            f[i][now]=f[q[l]][last]+sum[q[l]]*(sum[i]-sum[q[l]]);            y[i][now]=sum[i]*sum[i]-f[i][now];            while (l<r&&(y[q[r-1]][last]-y[q[r]][last])*(sum[q[r]]-sum[i])>=(y[q[r]][last]-y[i][last])*(sum[q[r-1]]-sum[q[r]])) r--;            q[++r]=i;        }    }    printf("%lld\n",f[n][now]);    return 0;}
0 0