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 }

你可能感兴趣的:(sleep)