标签:就是 不为 最大 i++ run 不能 return 休息 pre
设\(dp[i][j]\)为第\(i\)分钟,疲劳度为\(j\)的最大跑步距离。
发现了一种叫做“刷表法”的东西。我虽然不知道是什么东西,但是第一次写的时候就是用这种思想。
刷表法就是用已知的信息来更新后面的信息。而想记忆化搜索、普通递推的,叫做填表法。
下面是更新的方法:
你可以休息,连你疲劳度为0也可以。\(dp[i + 1][0] = max(dp[i + 1][0], dp[i][0])\)
疲劳度不为0的时候,设为\(j\),显然需要\(j\)天才休息好。\(dp[i + j][0] = max(dp[i + j][0], dp[i][j])\)
你可以跑步。\(dp[i + 1][j + 1] = dp[i][j] + d[i + 1]\)(这里注意是\(d[i + 1]\),因为你更新的是\(i +1\)天的状态)
你疲劳度为m的时候就不能继续跑了,所以上面注意。
你数组不要只开大5个。不然RE。
即使你最终答案是\(dp[n][0]\),你\(i\)也要取\(n\)。
你需要先讨论休息,后讨论跑步。
代码:
#include<cstdio>
#include<algorithm>
const int maxn = 10505, maxm = 505;
int dp[maxn][maxm];
int d[maxn];
int n, m;
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &d[i]);
dp[1][0] = 0; dp[1][1] = d[1];
for(int i = 1; i <= n; i++)
{
for(int j = 0; j <= m; j++)
{
if(j) dp[i + j][0] = std::max(dp[i + j][0], dp[i][j]);
else dp[i + 1][0] = std::max(dp[i + 1][0], dp[i][0]);
if(j != m) dp[i + 1][j + 1] = std::max(dp[i + 1][j + 1], dp[i][j] + d[i + 1]);
}
}
printf("%d\n", dp[n][0]);
return 0;
}
标签:就是 不为 最大 i++ run 不能 return 休息 pre
原文地址:https://www.cnblogs.com/Garen-Wang/p/9350972.html