Running
题目链接:
http://poj.org/problem?id=3661
题意:
有一只牛在跑步,在第 i 分钟它可以跑Ni米,疲惫值加1(疲惫值初始为0),或者休息一分钟,疲惫值减1(只有疲惫值到了0才能重新开始跑步),当匹配值达到M时它必须休息,且第N分钟结束时牛的疲惫值必须为0,求这只牛最远可以跑几米。
题解:
设dp[i][j]在 i 分钟里疲惫值限制为j的情况下牛可以跑的最远距离。一般情况下这样设就行了,但是因为题目限制只要开始休息就必须休息到疲惫值为0,所以这里将dp再加一重变成dp[i][j][0]和dp[i][j][1],分别代表在第 i 分钟能量为 j 时是休息还是继续跑步
很明显dp[i][j][0]是dp[i-1][j+1][0]和dp[i-1][j+1][1]间的较大值,注意当j==0的时候dp[i][j][0]还可以由dp[i-1][j][0]得到(即上一分钟能量已经为0,但是这一分钟还是休息)
而dp[i][j][1]=dp[i-1][j-1][1]+a[i](上一分钟跑步,这一分钟还在跑步),同样,这里也要注意一点,当j==1时dp[i][j][1]还可以由dp[i-1][j+1][1]+a[i]得到(上一分钟休息且疲惫值归0了)
代码
#include<stdio.h>
#include<string.h>
const int N=10001;
const int M=501;
int dp[N][M][2];
int mmax(int x,int y)
{
return x>y?x:y;
}
void solve()
{
int n,m,x;
memset(dp,0,sizeof(dp));
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;++i)
{
scanf("%d",&x);
for(int j=0;j<=m;++j)
{
if(j!=0)
{
dp[i][j][1]=dp[i-1][j-1][1]+x;
if(j==1)dp[i][j][1]=mmax(dp[i][j][1],dp[i-1][j-1][0]+x);
}
if(j!=m)
{
dp[i][j][0]=mmax(dp[i-1][j+1][0],dp[i-1][j+1][1]);
if(j==0)dp[i][j][0]=mmax(dp[i][j][0],dp[i-1][j][0]);
}
}
}
printf("%d
",dp[n][0][0]);
}
}
int main()
{
solve();
return 0;
}