动规之hdu3905--Sleeping

hdu3905--Sleeping

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others)
Total Submission(s): 1495    Accepted Submission(s): 565


Problem Description

       ZZZ is an enthusiastic ACMer and he spends lots of time on training. He always stays up late for training. He needs enough time to sleep, and hates skipping classes. So he always sleeps in the class. With the final exams coming, he has to spare some time to listen to the teacher. Today, he hears that the teacher will have a revision class. The class is N (1 <= N <= 1000) minutes long. If ZZZ listens to the teacher in the i-th minute, he can get Ai points (1<=Ai<=1000). If he starts listening, he will listen to the teacher at least L (1 <= L <= N) minutes consecutively. It`s the most important that he must have at least M (1 <= M <= N) minutes for sleeping (the M minutes needn`t be consecutive). Suppose ZZZ knows the points he can get in every minute. Now help ZZZ to compute the maximal points he can get.
 

Input
The input contains several cases. The first line of each case contains three integers N, M, L mentioned in the description. The second line follows N integers separated by spaces. The i-th integer Ai means there are Ai points in the i-th minute.
 

Output
For each test case, output an integer, indicating the maximal points ZZZ can get.
 

Sample Input
  
  
10 3 3 1 2 3 4 5 6 7 8 9 10
 
Sample Output
  
  
49
 
题意:
          一节课有N分钟,至少要睡M分钟,每次醒来至少会清醒L分钟,每分钟有不同的价值v[i],醒着才可以获得,求可获得的最大价值。

思路:
           用dp做。
            dp[i][j]表示在i分钟内睡j分钟可以获得的最大价值,所以当 当i点睡着的时候价值为 dp[i-1][j-1]
            用Us[j]数组表示睡j分钟,从当前i点开始到至少i-l分钟都是清醒着所获的最大价值,即i点醒着的时候价值为 Us[j]
         两者的最大值即为所求
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn(a,b) (a>b?a:b)
int dp[1005][1005],dpp[1005];
int M,N,L,sum[1005],a[1005];

void fun()
{
    int i,j;
    for(i=1;i<=N;i++)
        for(j=0;j<=i&&j<=M;j++)
    {
        dp[i][j]=dp[i-1][j-1];//第i分钟睡了,所以最大价值就是d[i-1][j-1]
        if(i-j>=L)
        {
             dpp[j]=maxn(dpp[j]+a[i],dp[i-L][j]+sum[i]-sum[i-L]);//这里比较难理解,i分钟时睡j分钟所得的知识点是i-1时睡j分钟所得知识                                                                    点+a[i]与i-L分钟内睡j分钟+sum[i]-sum[i-l]中最大的一个
             dp[i][j]=maxn(dpp[j],dp[i][j]);
        }

    }
}

int main()
{
    int i;
    while(~scanf("%d %d %d",&N,&M,&L))
    {
        memset(dp,0,sizeof(dp));
        memset(dpp,0,sizeof(dpp));
        for(i=1,sum[0]=0;i<=N;i++)
        {
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        fun();
        printf("%d\n",dp[N][M]);
    }
}
小结:这道题还有一个很纠结的问题,依旧是编译器,如果用G++提交能A,但一换成C++就WA,原因还没查出来
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值