LETTers第五场-Sleeping -解题报告

题目描述:

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

题面建模:

    dp。

 首先dp[i][j]表示前i分钟有j分钟是睡觉时间, 如果第i分钟睡觉dp[i][j]=dp[i-1][j-1];

   第i分钟学习的话: dp[i][j]=max(dp[k][j]+score[i]-score[k]) (1<=k<=i-l)。 score[i]表示前i分钟的分数之和。

解题要点:

   注意边界的处理和dp数组的初始化,开始的时候应将dp[i][j]=0。

   另外就是求dp[i][j]时如果将k从1到i-l遍历会超时,需要一个memory数组,记录这里求出的最大值,那么转移方程改写为:

   dp[i][j]=Max(mem[i-1][j]+score[i]-score[i-1],dp[i-l][j]+score[i]-score[i-l]);

时空开销分析:

空间复杂度:O(n^2)。

时间复杂度:O(n^2)。

特别说明:

无。

程序:

#include <stdio.h>
#include <string.h>
int score[1010];
int mem[1010][1010];
int dp[1010][1010];
int Max(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(score,0,sizeof(score));
        memset(dp,0,sizeof(dp));
        memset(mem,0,sizeof(mem));
        for(i=1;i<=n;i++)
        {
            scanf("%d",score+i);
            score[i]+=score[i-1];
        }
        for(i=1;i<=n;i++)
            for(j=0;j<=m;j++)
            {
                if(i>=l+j)
                    dp[i][j]=Max(mem[i-1][j]+score[i]-score[i-1],dp[i-l][j]+score[i]-score[i-l]);
                 mem[i][j]=dp[i][j];
                if(j>=1)
                    dp[i][j]=Max(dp[i][j],dp[i-1][j-1]);
            }
        printf("%d\n",dp[n][m]);
    }
    return 1;
}

 

转载于:https://www.cnblogs.com/LETTers/archive/2012/04/21/2461108.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值