ZOJ 2972 Hurdles of 110m
简单DP。dp[i][j]表示完成第i段,有j体力的情况下,获得的最小时间,
然后就可以递推:
//高速跑
if(j-s[i].f1>=0)
dp[i][j-s[i].f1]=min(dp[i][j-s[i].f1],dp[i-1][j]+s[i].t1);
//中速跑
dp[i][j]=min(dp[i][j],dp[i-1][j]+s[i].t2);
//低速跑
dp[i][min(m,j+s[i].f2)]=min(dp[i][min(m,j+s[i].f2)],dp[i-1][j]+s[i].t3);
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; int T; const int maxn=100+20; int dp[maxn][maxn]; int n,m; struct X { int t1,t2,t3; int f1,f2; }s[maxn]; int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d%d%d%d%d",&s[i].t1,&s[i].t2,&s[i].t3,&s[i].f1,&s[i].f2); for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) dp[i][j]=0x7fffffff; //中速过 dp[1][m]=min(dp[1][m],s[1].t2); //高速过 if(m-s[1].f1>=0) dp[1][m-s[1].f1]=min(dp[1][m-s[1].f1],s[1].t1); //低速过 dp[1][m]=min(dp[1][m],s[1].t3); for(int i=2;i<=n;i++) { for(int j=0;j<=m;j++) { if(dp[i-1][j]!=0x7fffffff) { //高速跑 if(j-s[i].f1>=0) dp[i][j-s[i].f1]=min(dp[i][j-s[i].f1],dp[i-1][j]+s[i].t1); //中速跑 dp[i][j]=min(dp[i][j],dp[i-1][j]+s[i].t2); //低速跑 dp[i][min(m,j+s[i].f2)]=min(dp[i][min(m,j+s[i].f2)],dp[i-1][j]+s[i].t3); } } } int ans=0x7fffffff; for(int i=0;i<=m;i++) ans=min(ans,dp[n][i]); printf("%d\n",ans); } return 0; }