Running(区间dp)

The cows are trying to become better athletes, so Bessie is running on a track for exactly N (1 ≤ N ≤ 10,000) minutes. During each minute, she can choose to either run or rest for the whole minute.
The ultimate distance Bessie runs, though, depends on her ‘exhaustion factor’, which starts at 0. When she chooses to run in minute i, she will run exactly a distance of Di (1 ≤ Di ≤ 1,000) and her exhaustion factor will increase by 1 – but must never be allowed to exceed M (1 ≤ M ≤ 500). If she chooses to rest, her exhaustion factor will decrease by 1 for each minute she rests. She cannot commence running again until her exhaustion factor reaches 0. At that point, she can choose to run or rest.
At the end of the N minute workout, Bessie’s exaustion factor must be exactly 0, or she will not have enough energy left for the rest of the day.
Find the maximal distance Bessie can run.

  Input
  
   * Line 1: Two space-separated integers: N and M
  • Lines 2…N+1: Line i+1 contains the single integer: Di
    Output

  • Line 1: A single integer representing the largest distance Bessie can run while satisfying the conditions.
     
    Sample Input
    5 2
    5
    3
    4
    2
    10
    Sample Output
    9
    拿题思想:这是一个关于跑步要使能跑的最长距离问题,并且与疲劳度有关。所以这题用区间dp来解决问题,首先每分中跑的的距离不一样,在这分钟可以选则跑,或者休息,跑的话会怎加1的疲劳度,休息的话会减少1的疲劳度,而且一旦休息就得休息到疲劳度为零才可以继续奔跑;最后使结束时的疲劳度为零,并且保持最远距离;所以我们令dp[i][j]为第i分钟时疲劳度为j;所以对于每分钟来说有两种选择,要么跑,要么休息。
    最终解题步骤
    1)申明好需要用的变量;
    2)通过要求找出动态转移方程,跑的时候有dp[i][j]=dp[i-1][j-1]+d[i] (d[i]为相应分钟跑的距离);休息时疲劳度为零时有dp[i][0]=dp[i-1][0],当疲劳度不为零时dp[i][0]=max(dp[i-j][j]);
    遇到问题:下面是出现问题的代码;

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
int dp[10005][10005];
int d[1005];
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m))     //问题所在的地方;
        {
            for(int i=1;i<=n;i++)
                cin>>d[i];
            dp[0][0]=0;
            for(int i=1;i<=n;i++)
                {
                    dp[i][0]=dp[i-1][0];
                    for(int j=1;j<=m;j++)
                        {
                            if(i>j) dp[i][0]=max(dp[i-j][j],dp[i][0]);
                            dp[i][j]=dp[i-1][j-1]+d[i];
                        }
                }
            cout<<dp[n][0]<<endl;
        }
}

这个代码所出现的问题是while(scanf("%d%d",&n,&m))这里面的条件不完整,使按Ctrl+z运行结束时,还会进行输出,所以Output Limit;

下面时ac代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
int dp[10005][10005];
int d[10005];
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))  //~scanf("%d%d",&n,&m)等效于scanf("%d%d",&n,&m)!=EOF;
        {
            for(int i=1;i<=n;i++)
                cin>>d[i];
            dp[0][0]=0;
            for(int i=1;i<=n;i++)
                {
                    dp[i][0]=dp[i-1][0];
                    for(int j=1;j<=m;j++)
                        {
                            if(i>j) dp[i][0]=max(dp[i-j][j],dp[i][0]);
                            dp[i][j]=dp[i-1][j-1]+d[i];
                        }
                }
            cout<<dp[n][0]<<endl;
        }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值