hdu 3905 Sleeping

来源:互联网 发布:男士服装搭配软件 编辑:程序博客网 时间:2024/06/05 08:22

Sleeping

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


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 31 2 3 4 5 6 7 8 9 10
 

Sample Output
49
 

Source
2011 Multi-University Training Contest 7 - Host by ECNU
 

Recommend
xubiao
 
题目大意:一节课有n分钟,至少要睡m分钟,每次醒来至少会清醒L分钟,每分钟有不同的价值,醒着才可以获得,求可获得的最大价值。
思路:
因为v[i]>0,所以获得最大价值的时候只能睡m分钟。
用dp做。
dp[i][j]表示在第i分钟睡j分钟可以获得的最大价值,注意:在每一点的dp[i][j]都满足题目要求。
用up[j]数组表示,睡j分钟的时候,从当前i点开始到至少i-l分钟都是清醒着所获的最大价值。
当i点睡着的时候价值为 dp[i-1][j-1]
当i点醒着的时候价值为 up[j]

求两者的最大值

#include <iostream>#include<string.h>#include<stdio.h>using namespace std;int dp[1010][1010],up[1010];int s[1010];int n,l,m;int ma(int a,int b){    return a>b?a:b;}int main(){    int i,j,a;    while(~scanf("%d%d%d",&n,&m,&l))    {        s[0]=0;        for(i=1; i<=n; i++)        {            scanf("%d",&s[i]);            s[i]+=s[i-1];        }        memset(dp,0,sizeof dp);        memset(up,0,sizeof up);        for(i=1; i<=n; i++)        {            a=s[i]-s[i-1];//获取第i分钟的分数            for(j=0; j<=i&&j<=m; j++)            {    //不用担心j-1为负值。默认的dp[0][-1]为0.                dp[i][j]=dp[i-1][j-1];//第i分钟睡觉的价值。下面考虑第i分钟学习的最大价值                if(i-l>=j)//要保证在i之前至少有l分钟听课。不然第i分钟不能听课                  {                      up[j]=ma(up[j]+a,dp[i-l][j]+s[i]-s[i-l]);//up[j]表示在i之前至少有l-1分钟听课的最大价值                      dp[i][j]=ma(dp[i][j],up[j]);//dp[i - l][j] + sum[i] - sum[i - l]这样就可以保证至少i-l到l清醒了。                  }                               //up[j]中值就始终为i之前至少有l-1分钟听课的最大价值            }        }        printf("%d\n",dp[n][m]);    }    return 0;}

原创粉丝点击