Sleeping

Sleeping

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述

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.

输入
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.
输出
For each test case, output an integer, indicating the maximal points ZZZ can get.
样例输入
10 3 31 2 3 4 5 6 7 8 9 10
样例输出
49

题意:

一节课有n分钟,ZZZ每听一分钟课都能得到一定的分数,一旦她开始听课就必须要至少连续听L分钟,但是她每节课都要有m分钟的睡眠时间(这m分钟不连续),
问在不影响她睡觉的情况下, 她一节课最多能得多少分。。。

思路:比较难理解的dp, 特别是tdp[i]所代表的含义。

#include <stdio.h>
#include <string.h>

int dp[1001][1001], tdp[1001], sum[1001];  //dp[i][j]:前i分钟睡j分钟所得的最大价值, tdp[j]:前i分钟在睡j分钟的前题下, 所得的最大价值(至少i-l到i是学习的)

int mymax(int a, int b)
{
    return a > b ? a : b;
}

int main()
{
    int n, m, l, i, j;
    while(scanf("%d%d%d", &n, &m, &l) != EOF)
    {
        memset(dp, 0, sizeof(dp));
        memset(tdp, 0, sizeof(tdp));
        sum[0] = 0;
        for(i = 1; i <= n; i++)
        {
            scanf("%d", &sum[i]);
            sum[i] += sum[i-1];          //实时更新前i项和
        }
        for(i = 1; i <= n; i++)
        {
            for(j = 0; j <= m && j <= i; j++)
            {
                dp[i][j] = j >= 1 ? dp[i-1][j-1] : 0;    //初始化为第i分钟睡觉所得的价值
                if(i-j >= l)                        //若可以听完l分钟课
                {
                     tdp[j] = mymax(tdp[j]+sum[i]-sum[i-1], dp[i-l][j]+sum[i]-sum[i-l]);  //实时更新tdp[j]的值(最小的时候是dp[i-l][j]+...因为可以有学的时间超过l的比正好l的价值高)
                }
                dp[i][j] = mymax(tdp[j], dp[i][j]);   //睡和不睡求最大
            }
        }
        printf("%d\n", dp[n][m]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值