bnuoj16491
http://www.bnuoj.com/bnuoj/problem_show.php?pid=16491
题意:有t组测试数据,每组测试数据第一行为n,m,接下来有n种跑法,m为最大的能力,每一种跑法占一行,有a,b,c,d,e。a表示快速跑完这段路途需要的时间,b表示平速跑完这段路途需要的时间,c表示慢速跑完需要花得时间,d表示快速跑完需要消耗的能量,e表示慢速跑完需要小号的能量,平速跑需要消耗的能量为0,问跑完n段路途所需要花得最少时间。
Sample Input
2 1 10 1 2 3 10 10 4 10 1 2 3 10 10 1 10 10 10 10 1 1 2 10 10 1 10 10 10 10
Sample Output
1 6
思路:对于这类多种状态的dp,一般是需要将它的某一个值放入数组,然后将其所要求的值求出来。
这道题,需要开二维,dp[i][j]表示,在第i段路途还有j点能量的时候所花的最少时间.....动态转移很好写,以前做过的题目中也有这类型的,这里不再重复‘
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define M 100000005 int dp[150][150]; int s[150][7]; int main() { int text; scanf("%d",&text); while(text--) { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { for(int j=0;j<5;j++) scanf("%d",&s[i][j]); } for(int i=0;i<=130;i++) for(int j=0;j<=130;j++) dp[i][j]=M; for(int i=0;i<=130;i++) dp[0][i]=0; for(int i=1;i<=n;i++) { for(int j=m;j>=0;j--) { if(j>=s[i][3]) { int ans=j-s[i][3]; if(dp[i][ans]>dp[i-1][j]+s[i][0]) dp[i][ans]=dp[i-1][j]+s[i][0]; } if(dp[i][j]>dp[i-1][j]+s[i][1]) dp[i][j]=dp[i-1][j]+s[i][1]; int tmp=j+s[i][4]; if(tmp>m) tmp=m; if(dp[i][tmp]>dp[i-1][j]+s[i][2]) dp[i][tmp]=dp[i-1][j]+s[i][2]; } } int minx=M; for(int i=0;i<=m;i++) if(dp[n][i]<minx) minx=dp[n][i]; printf("%d\n",minx); } return 0; }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。