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\n",dp[n][0][0]); } } int main() { solve(); return 0; }
时间: 2024-11-08 11:21:14