BZOJ 1010: [HNOI2008]玩具装箱toy(DP+斜率优化)
参考题解,解方程都解错。。和HDU3507 有点类似。其中还要运用换元,数学能力太弱了。
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #define N 500001 5 long long dp[N],que[N],p[N],sum[N]; 6 int m; 7 double slope(int x,int y) 8 { 9 if(sum[x] == sum[y]) 10 { 11 if(dp[x] > dp[y]) 12 return -1; 13 else 14 return 2147483647; 15 } 16 return (dp[x]-dp[y]+sum[x]*sum[x]-sum[y]*sum[y])*1.0/(sum[x]-sum[y]); 17 } 18 int main() 19 { 20 int n,i,str,end; 21 scanf("%d%d",&n,&m); 22 m ++; 23 for(i = 1; i <= n; i ++) 24 { 25 scanf("%lld",&p[i]); 26 sum[i] = p[i]+sum[i-1]; 27 } 28 for(i = 1; i <= n; i ++) 29 { 30 sum[i] = sum[i] + i; 31 } 32 str = end = 0; 33 for(i = 1; i <= n; i ++) 34 { 35 while(str < end&&slope(que[str],que[str+1]) <= 2*(sum[i]-m)) 36 str ++; 37 dp[i] = dp[que[str]] + (sum[i]-sum[que[str]]-m)*(sum[i]-sum[que[str]]-m); 38 while(str < end&&slope(que[end-1],que[end]) >= slope(que[end],i)) 39 end --; 40 end ++; 41 que[end] = i; 42 } 43 printf("%lld\n",dp[n]); 44 return 0; 45 }