BZOJ 1911: [Apio2010]特别行动队(斜率优化+DP)
算是斜率优化的经典题吧,公式好像挺好就能推出来,特别注意要long long,写写 居然还超时,托了一段时间,看了AC大神的题解,发现中间处理写搓了,计算的时候要记忆化,各种细节要注意,各种WA和TLE终于完成这个渣代码。。。
还可以把求解时候再优化一下,这样1800+水过了。。。
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #define N 1000001 5 #define eps 1e-9 6 long long p[N],que[N]; 7 long long a,b,c; 8 long long dp[N],sum[N]; 9 long long fx[N]; 10 long long f(int x)//记忆化一下 11 { 12 if(fx[x] > 0) 13 return fx[x]; 14 fx[x] = dp[x]+a*sum[x]*sum[x]-b*sum[x]; 15 return fx[x]; 16 } 17 double slope(int x,int y)//计算斜率 18 { 19 return (f(y)-f(x))*1.0/(sum[y]-sum[x]); 20 } 21 int main() 22 { 23 int i,n,str,end; 24 scanf("%d",&n); 25 scanf("%lld%lld%lld",&a,&b,&c); 26 for(i = 1; i <= n; i ++) 27 { 28 scanf("%lld",&p[i]); 29 sum[i] = sum[i-1] + p[i]; 30 } 31 str = end = 0; 32 for(i = 1; i <= n; i ++) 33 { 34 while(str < end&&slope(que[str],que[str+1]) - 2*a*sum[i] > eps)//维护队列 35 str ++; 36 dp[i] = dp[que[str]] + a*(sum[i]-sum[que[str]])*(sum[i]-sum[que[str]])+b*(sum[i]-sum[que[str]])+c;//这里可以再优化一下。。 37 while(str < end&&slope(que[end],i) - slope(que[end-1],que[end]) > eps)//维护队列 38 end --; 39 end ++; 40 que[end] = i; 41 } 42 printf("%lld\n",dp[n]); 43 return 0; 44 }