百练 / 2018大数据研究中心夏令营上机考试 D: 跑步

题目来源:https://www.luogu.org/problemnew/show/P1353

D:跑步

总时间限制1000ms    内存限制65536kB

描述

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

输入

1:2个用空格隔开的整数:N M
2..N+1:i+11个整数:D_i

输出

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

样例输入

5 2
5
3
4
2
10

样例输出

9

提示

对于30%的数据,N<= 50, M <= 10

来源

USACO 2008 January Silver

--------------------------------------------------------------

思路

动态规划

f[i][j]:第i分钟疲劳程度为j时跑步的距离,如果第i分钟时疲劳度j不可能达到或此时正在休息疲劳度尚未恢复到0, f[i][j] = -1

递推时分跑步和休息两种情况讨论,注意题干里的这句话:“如果贝茜选择休息,那么她的疲劳度就会每分钟减少1但她必须休息到疲劳度恢复到0为止

-----------------------------------------------------

代码 

#include
#include
using namespace std;

const int NMAX = 10010, MMAX = 505;
int a[NMAX] = {};
int f[NMAX][MMAX] = {};			// 第i分钟疲劳程度为j时跑步的距离, 如果第i分钟不能开始跑步(正在休息),f[i][j] = -1

int main()
{
#ifndef ONLINE_JUDGE
	ifstream fin ("D.txt");
	int n,m,i,j;
	fin >> n >> m;
	for (i=1; i<=n; i++)
	{
		fin >> a[i];
	}
	fin.close();
	for (i=0; i=0)
			{
				if (j0)
				{
					if (f[i-1][j] + a[i] > f[i][j+1])
						f[i][j+1] = f[i-1][j] + a[i];				// 第i分钟跑步
					if (i-1+j <= n && f[i-1][j] > f[i-1+j][0])
						f[i-1+j][0] = f[i-1][j];					// 第i分钟休息直到第i-1+j分钟
				}
				else if (j==m)
				{
					if (i-1+m <= n && f[i-1][j] > f[i][j-1])
						f[i-1+m][0] = f[i-1][j];					// 疲劳度达到m只能休息
				}
				else if (j==0)
				{
					if (f[i-1][0] + a[i] > f[i][1])
						f[i][1] = f[i-1][0] + a[i];					// 第i分钟跑步
					if (f[i-1][0] > f[i][0])
						f[i][0] = f[i-1][0];						// 疲劳度为0休息了也没用
				}
			}
		}
	}
	cout << f[n][0];
	return 0;
#endif
#ifdef ONLINE_JUDGE
	int n,m,i,j;
	cin >> n >> m;
	for (i=1; i<=n; i++)
	{
		cin >> a[i];
	}
	for (i=0; i=0)
			{
				if (j0)
				{
					if (f[i-1][j] + a[i] > f[i][j+1])
						f[i][j+1] = f[i-1][j] + a[i];				// 第i分钟跑步
					if (i-1+j <= n && f[i-1][j] > f[i-1+j][0])
						f[i-1+j][0] = f[i-1][j];					// 第i分钟休息直到第i-1+j分钟
				}
				else if (j==m)
				{
					if (i-1+m <= n && f[i-1][j] > f[i][j-1])
						f[i-1+m][0] = f[i-1][j];					// 疲劳度达到m只能休息
				}
				else if (j==0)
				{
					if (f[i-1][0] + a[i] > f[i][1])
						f[i][1] = f[i-1][0] + a[i];					// 第i分钟跑步
					if (f[i-1][0] > f[i][0])
						f[i][0] = f[i-1][0];						// 疲劳度为0休息了也没用
				}
			}
		}
	}
	cout << f[n][0];
	return 0;
#endif
}


你可能感兴趣的:(百练OJ/poj)