您的位置:首页 > 其它

【斜率优化】BZOJ1010 [HNOI2008]玩具装箱toy

2016-05-14 19:57 399 查看
【题目大意】

P教授有编号为1...N的N件玩具,第i件玩具长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的。如果将第i件玩具到第j个玩具放到一 个容器中,那么容器的长度将为 x=j-i+Sigma(Ck) i<=K<=j 制作容器的费用与容器的长度有关, 如果容器长度为x,其制作费用为(X-L)^2.其中L是一个常量。求最小费用。

【思路】

懒得说了,把WC宋新波老师的课件搬运一下。




















宋新波老师讲的很好,WC的时候第一次听斜率优化听他讲完秒懂了,时隔几个月再来消化一下。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MAXN=50000+50;
int n,l;
int c[MAXN];
LL s[MAXN],g[MAXN],x[MAXN],y[MAXN],f[MAXN];

LL square(LL x)
{
return x*x;
}

double slop(int i,int j)
{
return ((y[j]-y[i])/(x[j]-x[i]));
}

void dp()
{
memset(f,0,sizeof(f));
int head=0,tail=0;
int q[MAXN];
q[head]=0;
for (int i=1;i<=n;i++)
{
y[i]=f[i-1]+square(x[i]);
while (head+1<tail && slop(q[tail-2],q[tail-1])>slop(q[tail-1],i)) tail--;
q[tail++]=i;
while (head+1<tail && slop(q[head],q[head+1])<2.0*g[i]) head++;
f[i]=f[q[head]-1]+square(g[i]-x[q[head]]);
}
}

void init()
{
scanf("%d%d",&n,&l);
memset(s,0,sizeof(s));
for (int i=1;i<=n;i++)
{
scanf("%d",&c[i]);
s[i]=s[i-1]+c[i];
g[i]=s[i]+i-l;
x[i]=s[i-1]+i;
}
}

void printans()
{
printf("%lld",f
);
}

int main()
{
init();
dp();
printans();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: