bzoj 1911: [Apio2010]特别行动队

Description

Input

Output

Sample Input

4
-1 10 -20
2 2 3 4

Sample Output

9

HINT

Source

 

MDZZ又是一道类似玩具装箱的划分型DP。。。

单调性的话 貌似 f[i]=min/max(f[j]+w[i,j])的转移都有单调性。。。

所以拿来练二分栈的板子了。。。

和n^2对拍没有问题就交了。。。

1000000一开始吓死我了,然而过了。。。

 

 1 // MADE BY QT666
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<queue>
 7 #include<set>
 8 #include<cstdlib>
 9 #include<cstring>
10 #include<string>
11 #include<ctime>
12 #define lson num<<1
13 #define rson num<<1|1
14 #define int long long
15 using namespace std;
16 typedef long long ll;
17 const int N=1000050;
18 int gi()
19 {
20   int x=0,flag=1;
21   char ch=getchar();
22   while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}
23   while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
24   return x*flag;
25 }
26 int a,b,c,n;
27 int s[N],f[N];
28 struct data{int l,r,p;}q[N];
29 int work(int x){
30     return a*x*x+b*x+c;
31 }
32 int cal(int j,int i){
33     return f[j]+work(s[i]-s[j]);
34 }
35 int find(data t,int x)
36 {
37     int l=t.l,r=t.r;
38     while(l<=r){
39       int mid=(l+r)>>1;
40       if(cal(t.p,mid)>cal(x,mid))
41             l=mid+1;
42           else r=mid-1;
43     }
44     return l;
45 }
46 main()
47 
48     n=gi();
49     a=gi(),b=gi(),c=gi();
50     for(int i=1;i<=n;i++) s[i]=gi(),s[i]+=s[i-1];
51     int head=1,tail=0;
52     q[++tail]=(data){0,n,0};
53     for(int i=1;i<=n;i++){
54         if(head<=tail&&i>q[head].r)head++;
55         f[i]=cal(q[head].p,i);
56         if(head>tail||cal(i,n)>=cal(q[tail].p,n)){
57             while(head<=tail&&cal(i,q[tail].l)>=cal(q[tail].p,q[tail].l))
58                 tail--;
59             if(head>tail)
60                 q[++tail]=(data){i,n,i};
61             else{
62                 int t=find(q[tail],i);
63                 q[tail].r=t-1;
64                 q[++tail]=(data){t,n,i};
65             }
66         }
67     }
68     printf("%lld\n",f[n]);
69 }

 

 

posted @ 2017-03-06 22:04  qt666  阅读(160)  评论(0编辑  收藏  举报