玩具装箱 bzoj1010 斜率优化

斜率优化的题好像都是这样的方程:左边关于j,k的一个(...)/(...)的式子,右边是个只与i有关的可算的数字;

然后把它放到二维坐标轴上,用单调队列维护一个凸壳,O(n)的复杂度;

这道题但是我发现我wrong了,找了程序看了一下,才发现斜率优化还有一点没理解;才明白上午T2能A是由于数据太水,出题人万岁!

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 #define LL long long
 5 const int maxn=50500;
 6 LL n,L,a[maxn],g[maxn],q[maxn],tail=0,head=1,f[maxn];
 7 void init(){
 8     freopen("1.in","r",stdin);
 9     freopen("1.out","w",stdout);
10     scanf("%d%d",&n,&L);
11     for(int i=1;i<=n;i++){
12         scanf("%d",&a[i]);
13         g[i]=g[i-1]+a[i];
14     }
15 }
16 double p(LL k,LL j){
17     return double(f[j]+g[j]*g[j]-f[k]-g[k]*g[k])/(double)(2*(g[j]-g[k]));
18 }
19 LL squ(LL x){return x*x;}
20 void work(){
21     for(int i=1;i<=n;i++)g[i]+=i;
22     q[++tail]=0;
23     for(int i=1;i<=n;i++){
24         while(head<tail&&p(q[head],q[head+1])<g[i]-1-L)head++;
25         cout<<q[head]<<endl;
26         f[i]=f[q[head]]+squ(g[i]-g[q[head]]-L-1);
27         while(head<tail&&p(q[tail],i)<p(q[tail],q[tail-1]))tail--;
28         q[++tail]=i;
29     }
30     cout<<f[n]<<endl;
31 }
32 int main(){
33     init();
34     work();
35 }
View Code

 

posted @ 2016-09-04 22:03  CHADLZX  阅读(127)  评论(0编辑  收藏  举报