HDU 3905 Sleeping dp

本文描述了一个ACM竞赛选手在有限时间内既要保证听课获取分数又要确保足够休息的问题。通过动态规划算法来找到最佳的听讲与休息策略,以最大化得分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Sleeping

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


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
 

Source

璇渣开始补dp Q_Q

n分钟的课 听第i分钟可获得ai分 睡觉不得分

至少睡m分,每次听课必须连续>=L 分钟,求最大得分。

dp[i][j][0] 表示前 i 分钟睡觉了 j 分钟而且第 i 分钟没有睡觉,dp[i][j][1] 表示前 i 分钟睡觉了 j 分钟而且第 i 分钟在睡觉。则:
dp[i][j][1] = max(dp[i-1][j-1][0], dp[i-1][j-1][1]);
dp[i][j][0] = max(dp[i-L][j][1]+sum[i]-sum[i-L], dp[i-1][j][0]+a[i]);


/** Author: ☆·aosaki(*’(OO)’*)  niconiconi★ **/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <functional>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <list>
#include <stack>
//#include <tuple>
#define mem(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define lp(k,a) for(int k=1;k<=a;k++)
#define lp0(k,a) for(int k=0;k<a;k++)
#define lpn(k,n,a) for(int k=n;k<=a;k++)
#define lpd(k,n,a) for(int k=n;k>=a;k--)
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d %d",&a,&b)
#define lowbit(x) (x&(-x))
#define ll long long
#define pi pair<int,int>
#define vi vector<int>
#define PI acos(-1.0)
#define pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)
#define TT cout<<"*****"<<endl;
#define TTT cout<<"********"<<endl;
inline int gcd(int a,int b)
{
    return a==0?b:gcd(b%a,a);
}

#define INF 1e9
#define eps 1e-8
#define mod 10007
#define MAX 1002

using namespace std;


int dp[1005][1005][2];
int a[1005],sum[1005];

int main()
{
    //freopen("in.txt","r",stdin);
    int n,m,L;
    while (~scanf("%d%d%d",&n,&m,&L))
    {
        mem(sum); mem(dp);
        lp(i,n)
          sc(a[i]);
        lp(i,n)
            sum[i]=sum[i-1]+a[i];
        lp(i,n)
        {
            if(i>=L)
                dp[i][0][0]=sum[i];
            for (int j=1;j<=m && j<=i;j++)
            {
                dp[i][j][1]=max(dp[i-1][j-1][0], dp[i-1][j-1][1]);
                if(i-L>=j)
                  dp[i][j][0]=max(dp[i-L][j][1]+sum[i]-sum[i-L], dp[i-1][j][0]+a[i]);
            }
        }
        printf("%d\n",max(dp[n][m][0],dp[n][m][1]));
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值