【题解】menit的运动计划

题目描述

monkeys打算通过跑步来培养自己的运动细胞,作为其中的一员,menit选择的运动方式是每天进行 \(N(1\le N\le10000)\) 分钟的跑步训练。在每分钟的开始,menit会选择下一分钟是用来跑步还是停下休息。
menit的体力限制了她跑步的距离。更具体地,如果menit选择在第 \(i\) 分钟内跑步,她可以在这一分钟内跑 \(D_i(1\le D_i\le1000)\) 米,并且她的疲劳度会增加 \(1\) 。不过,无论何时menit的疲劳度都不能超过 \(M(1\le M\le500)\)。如果menit选择停下休息,那么她的疲劳度就会每分钟减少 \(1\) ,但她必须休息到疲劳度恢复到 \(0\) 为止。在疲劳度为0时休息的话,疲劳度不会再变动。跑步开始时,menit的疲劳度为 \(0\) 。 还有,在 \(N\) 分钟的跑步训练结束时,menit的疲劳度也必须恢复到 \(0\),否则她将没有足够的精力来对付这一整天中剩下的事情。 请你计算一下,menit最多能跑多少米。

输入格式

\(1\) 行: \(2\) 个用空格隔开的整数:\(N\)\(M\)\(2..N+1\) 行: 第 \(i+1\)\(1\) 个整数:\(D_i\)

输出格式

输出 \(1\) 个整数,表示在满足所有限制条件的情况下,menit能跑的最大距离

样例

样例输入
5 2
5
3
4
2
10
样例输出
9
样例说明

menit在第 \(1\) 分钟内选择跑步(跑了 \(5\) 米),在第 \(2\) 分钟内停下来休息,在第 \(3\) 分钟内跑步(跑了 \(4\) 米),剩余的时间都用来休息。因为在跑步结束时menit的疲劳度必须为 \(0\) ,所以她不能在第 \(5\) 分钟内选择跑步。

数据范围与提示

\(10\%\)数据 \(n\le5\)
\(40\%\)数据 \(n\le100\)
\(100\%\)数据 \(n\le10000,m\le500\)

Solution

简单DP。
设计状态:

f[i][j] 表示第 i 分钟,疲劳值为 j 的最大方案

状态转移方程:

对于 \(f[i][0]\) 来说,自己可以等于 \(k\) 分钟前,疲劳度刚好为 \(k\) 的值或上一分钟休息,这一分钟继续休息的值。

对于 \(f[i][j](j>0)\) 来说,自己只能等于上一分钟,疲劳值减一加上这一分钟可以跑的距离。

由此推出状态转移方程:

\[f[i][j]=\begin{cases}\max(\max\{f[i-k][k]\},f[i-1][0])&j=0\\f[i-1][j-1]+d[i]&j>0\end{cases} \]

Code
#include<cstdio>
int n,m;
int d[10005];
int f[10005][505];
int max(int x,int y){
	return x>y?x:y;
}
int main(){
	freopen("cowrun.in","r",stdin);
	freopen("cowrun.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		scanf("%d",&d[i]);
	for(int i=1;i<=n;++i){
		f[i][0]=f[i-1][0];
		for(int j=1;j<=i;++j)
			f[i][0]=max(f[i][0],f[i-j][j]);
		for(int j=1;j<=m;++j)
			f[i][j]=max(f[i][j],f[i-1][j-1]+d[i]);
	}
	printf("%d",f[n][0]);
	return 0;
}

end.

posted @ 2020-11-13 19:43  XSC062  阅读(137)  评论(0编辑  收藏  举报