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 }