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 }
posted @ 2012-09-03 11:28  Naix_x  阅读(142)  评论(0编辑  收藏  举报