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

【题目大意】

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

【思路】

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

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

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 const int MAXN=50000+50;
 8 int n,l;
 9 int c[MAXN];
10 LL s[MAXN],g[MAXN],x[MAXN],y[MAXN],f[MAXN];
11  
12 LL square(LL x)
13 {
14     return x*x;
15 }
16  
17 double slop(int i,int j)
18 {
19     return ((y[j]-y[i])/(x[j]-x[i]));
20 }
21  
22 void dp()
23 {
24     memset(f,0,sizeof(f));
25     int head=0,tail=0;
26     int q[MAXN];
27     q[head]=0;
28     for (int i=1;i<=n;i++)
29     {
30         y[i]=f[i-1]+square(x[i]);
31         while (head+1<tail && slop(q[tail-2],q[tail-1])>slop(q[tail-1],i)) tail--;
32         q[tail++]=i;
33         while (head+1<tail && slop(q[head],q[head+1])<2.0*g[i]) head++;
34         f[i]=f[q[head]-1]+square(g[i]-x[q[head]]);
35     }
36 }
37  
38 void init()
39 {
40     scanf("%d%d",&n,&l);
41     memset(s,0,sizeof(s));
42     for (int i=1;i<=n;i++)
43     {
44         scanf("%d",&c[i]);
45         s[i]=s[i-1]+c[i];
46         g[i]=s[i]+i-l;
47         x[i]=s[i-1]+i;
48     }
49 }
50  
51 void printans()
52 {
53     printf("%lld",f[n]); 
54 }
55  
56 int main()
57 {
58     init();
59     dp();
60     printans();
61     return 0;
62 }
原文地址:https://www.cnblogs.com/iiyiyi/p/5493202.html