奶牛们打算通过锻炼来培养自己的运动细胞,作为其中的一员,贝茜选择的 运动方式是每天进行N(1 <= N <= 10,000)分钟的晨跑。在每分钟的开始,贝茜 会选择下一分钟是用来跑步还是休息。 贝茜的体力限制了她跑步的距离。更具体地,如果贝茜选择在第i分钟内跑 步,她可以在这一分钟内跑D_i(1 <= D_i <= 1,000)米,并且她的疲劳度会增加
1。不过,无论何时贝茜的疲劳度都不能超过M(1 <= M <= 500)。如果贝茜选择 休息,那么她的疲劳度就会每分钟减少1,但她必须休息到疲劳度恢复到0为止。 在疲劳度为0时休息的话,疲劳度不会再变动。晨跑开始时,贝茜的疲劳度为0。 还有,在N分钟的锻炼结束时,贝茜的疲劳度也必须恢复到0,否则她将没有 足够的精力来对付这一整天中剩下的事情。 请你计算一下,贝茜最多能跑多少米。
这题一看就是个二维DP
dp[i , j]表示第i秒疲劳度为j的最大距离。
首先dp[i, 0] = dp[i - 1, 0]是一定可以的。
然后就可以枚举疲劳度。
dp[i, 0] = max(dp[i, 0], dp[i - j, j]) j <= i
dp[i, j] = max(dp[i , j], dp[i - 1, j - 1] + a[i]) j <= M
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cstdlib> #include <ctime> #include <vector> #include <map> #include <set> #define MAXN 11111 #define MAXM 555 #define INF 1000000007 using namespace std; int dp[MAXN][MAXM]; int a[MAXN]; int n, m; int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); 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][0], dp[i - j][j]); dp[i][j] = max(dp[i - 1][j - 1] + a[i], dp[i][j]); } } printf("%d\n", dp[n][0]); return 0; }