HDU 3905 Sleeping(单调优化DP)

题目链接

这个状态转移想了会时间,dp[i][j]记录前i分钟学了j分钟的取得的最大的分数,得到方程dp[i][j] = dp[i-k][j-k] + sum[i] - sum[i-k](l<=k<=j) ,这个果断并不是只是一个普通的DP,交上各种TLE,然后发现问题了,应该需要需要优化。这个状态方程神似以前单调队列优化DP的转移方程,只不过改成对角线了,而且只需维护队列的队头即可。对这部分还是不太自信啊,试着写了写,反正感觉写的不太好,WA了多次,乱改了几次后过了。。。不容易啊。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 int dp[1001][1001],p[1001],sum[1001],que[1001];
 6 int main()
 7 {
 8     int i,j,k,n,m,l;
 9     while(scanf("%d%d%d",&n,&m,&l)!=EOF)
10     {
11         memset(dp,0,sizeof(dp));
12         memset(sum,0,sizeof(sum));
13         for(i = 1;i <= n;i ++)
14         {
15             scanf("%d",&p[i]);
16             sum[i] = sum[i-1] + p[i];
17         }
18         for(i = 1;i <= n;i ++)//初始化队列
19         que[i] = i;
20         for(i = l;i <= n;i ++)
21         {
22             for(j = l;j <= i&&j <= n-m;j ++)
23             {
24                 dp[i][j] = dp[i-1][j];
25                 if(dp[i-l][j-l]-sum[i-l] > dp[que[i-j+1]][que[i-j+1]+j-i]-sum[que[i-j+1]])
26                 {
27                     que[i-j+1] = i-l;
28                 }
29                 if(dp[i][j] < dp[que[i-j+1]][que[i-j+1]+j-i]+sum[i]-sum[que[i-j+1]])
30                 dp[i][j] = dp[que[i-j+1]][que[i-j+1]+j-i]+sum[i]-sum[que[i-j+1]];
31             }
32         }
33         printf("%d\n",dp[n][n-m]);
34     }
35     return 0;
36 }
posted @ 2012-10-17 18:57  Naix_x  阅读(211)  评论(0)    收藏  举报