您的位置:首页 > 其它

bzoj3675 [Apio2014]序列分割

2017-10-11 16:09 337 查看
传送门

好久都没写blog了啊。。。主要是懒。。。

今天做了几道斜率优化dp题,感觉这是最有价值的一道,发出来存一下。。。

首先题目要求将一个序列划分k次,一次划分的贡献是被划分出两部分的乘积。有一个结论:切的先后没有影响。。果然猜结论是一种很重要的能力= =

然后就可以化式子斜率优化了,,,注意滚动数组的细节!

CODE:

#include<cstdio>
#define N 100005
typedef long long ll;
int q
,h,t;
ll f
[2],a
;
int n,k,tot;
inline double sqr(double x){return x*x;}
inline double slope(int i,int j,int wh){return (double)(f[i][wh^1]-f[j][wh^1]+sqr(a[j])-sqr(a[i]))/(double)(a[j]-a[i]);}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
if(a[i]) a[++tot]=a[i];
n=tot;
for(int i=1;i<=n;i++)
a[i]+=a[i-1];
for(int j=1;j<=k;j++)
{
h=t=0;q[0]=j-1;
for(int i=j;i<=n;i++)
{
while(h<t&&slope(q[h],q[h+1],j&1)<a[i]) h++;
f[i][j&1]=f[q[h]][~j&1]+a[q[h]]*(a[i]-a[q[h]]);
while(h<t&&slope(q[t-1],q[t],j&1)>slope(q[t],i,j&1)) t--;
q[++t]=i;
}
}
printf("%lld",f
[k&1]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息