DP起手练习5

题目描述

[USACO08JAN]Running S

奶牛们打算通过锻炼来培养自己的运动细胞,作为其中一员,贝茜选择的运动方式是每天进行n分钟的晨跑.在每分钟的开始,贝茜会选择下一分钟是用来跑步还是休息.

贝茜的体力限制了她跑步的距离。更具体地,如果贝茜选择在第i分钟内跑步,她可以在这一分钟内跑 d i {d_i} di米,并且她的疲劳度会增加1.不过,无论何时贝茜的疲劳度都不能超过m。

如果贝茜选择休息,那么她的疲劳度就会每分钟减少1,但她须休息到疲劳度恢复到0为止.在疲劳度为0时休息的话,疲劳度不会再变动.晨跑开始时,贝茜的疲劳度为0.
还有,在n分钟的锻炼结束时,贝茜的疲劳度也必须恢复到0,否则她将没有足够的精力来对付这一整天中剩下的事情。

请你计算一下,贝茜最多能跑多少米。

输入格式

第一行两个正整数 n,m。
接下来n行,每行一个正整数 d i {d_i} di

输出格式

输出一个整数,表示在满足所有限制条件的情况下,贝茜能跑的最大距离。

输入输出样例
输入 #1
5 2
5
3
4
2
10
输出 #1
9
说明/提示
对于100%的数据: 1 ≤ n ≤ 1 0 4 , 1 ≤ d i ≤ 1000 , 1 ≤ m ≤ 500. {1\le n \le 10^4 ,1\le d_i \le 1000,1\le m \le 500.} 1n104,1di1000,1m500.

思路

又是一道很适合新手的DP基础题,这道题我们依然可以很容易想到用m和n代表的条件来表示状态,即: f [ i ] [ j ] {f[i][j]} f[i][j]表示第 i {i} i分钟疲劳度为 j {j} j时跑的最大距离,其中我们有两种选择
第一种选择为:
休息到 j = 0 {j=0} j=0,此时若 j {j} j已经为0,则有: f [ i ] [ 0 ] = m a x ( f [ i − 1 ] [ 0 ] , f [ i ] [ 0 ] ) {f[i][0]=max(f[i-1][0],f[i][0])} f[i][0]=max(f[i1][0],f[i][0]),
否则: f [ i + j ] [ 0 ] = m a x ( f [ i ] [ j ] , f [ i + j ] [ 0 ] ) {f[i+j][0]=max(f[i][j],f[i+j][0])} f[i+j][0]=max(f[i][j],f[i+j][0]);
第二种选择:
继续跑,则有 f [ i + 1 ] [ j + 1 ] = m a x ( f [ i ] [ j ] + a [ i + 1 ] , f [ i + 1 ] [ j + 1 ] ) {f[i+1][j+1]=max(f[i][j]+a[i+1],f[i+1][j+1])} f[i+1][j+1]=max(f[i][j]+a[i+1],f[i+1][j+1]);
(加1是为了防止数组爆掉!)
最后 f [ n ] [ 0 ] {f[n][0]} f[n][0]便是我们要的答案了.(注意初始化: f [ 1 ] [ 1 ] = a [ 1 ] {f[1][1]=a[1]} f[1][1]=a[1]!)

代码

#include<bits/stdc++.h>
#define N 10505//取一万只多一点点会RE因为数组要装(n+m)!
using namespace std;

int n,m;
int f[N][520],a[N];

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	scanf("%d",&a[i]);
	f[1][1]=a[1];//初始化.
	for(int i=1;i<=n;i++)
		for(int j=0;j<=min(i,m);j++)
		{
			if(j==0)f[i][0]=max(f[i-1][0],f[i][0]);//特判,此时没必要休息更新答案
			else f[i+j][0]=max(f[i][j],f[i+j][0]);//休息
			f[i+1][j+1]=max(f[i+1][j+1],f[i][j]+a[i+1]);//继续跑	
		}
	cout<<f[n][0]<<endl;
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liaoxiyan123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值