bzoj 3675: [Apio2014]序列分割

(一开始决策单调性证错了。。(蛋疼)(其实是没有单调性的,怎么都一样),可以自己写一写i<j,先分i后分j,和先分j后分i是一样的)

(而且犇蒟蒻发现斜率优化随便推上一个式子就可以了,(感觉比DP简单多了(雾)))

 1 #include<cstdio>
 2 #include<iostream>
 3 #define LL long long
 4 #define lowbit(x) x&(-x)
 5 #define inf 0x3f3f3f3f
 6 #define eps 1e-5
 7 #define N 100005
 8 using namespace std;
 9 inline int ra()
10 {
11     int x=0,f=1; char ch=getchar();
12     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
13     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
14     return x*f;
15 }
16 LL f[N][2],sum[N],ans,a[N];
17 int q[N],n,K,top,pp,qq;
18 double slope(int b, int a)
19 {
20     return (double)(sum[b]*sum[b]-f[b][pp]+f[a][pp]-sum[a]*sum[a])/(double)(sum[b]-sum[a]);
21 }
22 int main(int argc, char const *argv[])
23 {
24     n=ra(); K=ra();
25     for (int i=1; i<=n; i++) a[i]=ra();
26     for (int i=1; i<=n; i++) if (a[i]!=0) sum[++top]=sum[top-1]+a[i];
27     n=top; pp=1,qq=0;
28     for (int k=1; k<=K; k++)
29     {    
30         int L=1,R=0;
31         for (int i=k; i<=n; i++)
32         { 
33             while (L<R && slope(i-1,q[R])<slope(q[R],q[R-1])) R--;
34             q[++R]=i-1;
35             while (L<R && slope(q[L+1],q[L])<sum[i]) L++; 
36             int t=q[L];
37             f[i][qq]=f[t][pp]+(sum[i]-sum[t])*sum[t];
38         }
39         pp^=1,qq^=1;
40     }
41     cout<<f[n][pp];
42     return 0;
43 }

 

posted @ 2017-03-13 20:50  ws_ccd  阅读(145)  评论(0编辑  收藏  举报