题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2972
题意就不用多说了,其实刚开始的时候一看就知道是一个动规的题目,在考虑状态转移方程的时候,用跳栏的顺序来做状态转移,越写越复杂。
后来比赛完了,问了同学,以体力为状态转移,就会简单很多。分三种情况求最优值就可以了。
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int dp[108][108];
int main(){
int t,n,m,i,j,sum;
int t1,t2,t3,f1,f2;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(i=0;i<=n+1;i++)
for(j=0;j<=m+1;j++){
dp[i][j]=99999999;
}
dp[0][m]=0;
for(i=1;i<=n;i++){
scanf("%d%d%d%d%d",&t1,&t2,&t3,&f1,&f2);
for(j=m;j>=0;j--){
dp[i][j]=min(dp[i][j],dp[i-1][j]+t2); //第二种情况
if(j>=f1){ //第一种,加速。。。。
dp[i][j-f1]=min(dp[i][j-f1],dp[i-1][j]+t1);
}
sum=j+f2;
if(sum > m) sum=m; //第三种情况。减速进行。。。。
dp[i][sum]=min(dp[i][sum],dp[i-1][j]+t3);
//printf(" %d\n",dp[i][j]);
}
}
int minn=99999999;
for(i=0;i<=m;i++){
//printf("%d ",dp[n][i]);
if(dp[n][i]<minn) minn=dp[n][i];
}
printf("%d\n",minn);
}
return 0;
}
路途中。。。。