题意
奶牛们打算通过锻炼来培养自己的运动细胞,作为其中的一员,贝茜选择的运动方式是每天进行 n n n 分钟的晨跑。在每分钟的开始,贝茜会选择下一分钟是用来跑步还是休息。
贝茜的体力限制了她跑步的距离。更具体地,如果贝茜选择在第 i i i 分钟内跑步,她可以在这一分钟内跑 d i d_i di米,并且她的疲劳度会增加 1。不过,无论何时贝茜的疲劳度都不能超过 m。
如果贝茜选择休息,那么她的疲劳度就会每分钟减少 1,但她必须休息到疲劳度恢复到 0 为止。在疲劳度为 0 时休息的话,疲劳度不会再变动。晨跑开始时,贝茜的疲劳度为 0 。
还有,在 n n n 分钟的锻炼结束时,贝茜的疲劳度也必须恢复到 0,否则她将没有足够的精力来对付这一整天中剩下的事情。
请你计算一下,贝茜最多能跑多少米。
题解
分析题目的变量:分钟数、疲劳度
分析题目的属性:求 M a x d i s Max_{dis} Maxdis
定义 f [ i ] [ j ] f[i][j] f[i][j] 为第 i i i 分钟,疲劳值为 j j j 的最大值的集合
把集合划分为跑或者不跑两种情况
- 在第 i i i 分钟选择跑
f [ i ] [ j ] = f [ i − 1 ] [ j − 1 ] + D i f[i][j]=f[i-1][j-1]+D_i f[i][j]=f[i−1][j−1]+Di
- 在第 i i i分钟选择休息
f [ i ] [ j ] = M a x ( f [ i − j ] [ j ] ) f[i][j]=Max(f[i-j][j]) f[i][j]=Max(f[i−j][j])
如果当前疲劳值为 j j j ,在 i − j i-j i−j 分钟开始休息,才能保证疲劳值为 0 0 0 (当Bessie要休息的时候,是要一休息就休息完剩下所有时间的,参见样例)
Code
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 8;
const int N = 1e5 + 7, M = 510;
int d[N];
int f[N][M];
int main() {
ios::sync_with_stdio(false);
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i++) {
cin >> d[i];
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
f[i][j] = f[i - 1][j - 1] + d[i];
}
f[i][0] = f[i - 1][0];
for(int j = 1; j <= i && j <= m; j++) {
f[i][0] = max(f[i][0], f[i - j][j]);
}
}
// for(int i = 0; i <= n; i++) {
// for(int j = 0; j <= m; j++) {
// cout << f[i][j] << ' ';
// }
// cout << endl;
// }
cout << f[n][0];
return 0;
}
/*
5 2
5
3
4
2
10
*/