HDU 2159 FATE 动态规划二维费用的背包问题
http://acm.hdu.edu.cn/showproblem.php?pid=2159
题意:
给出的n , m , k ,s 分别代表还需n经验升级、还有m耐久度、下面有k组数据、最多能杀s只怪,下面k组的a和b分别
代表杀一只这种怪要消耗b耐久度获得a经验,让你计算出在耐久度和杀怪数范围内能不能获得题目给出的经验。
坑爹:
一开始我想的时候以为是多重背包的问题,我以为是每种怪都能杀s次,其实是总共只能杀s只怪,所以不能用多重背包做。
解法:
二维费用的背包问题,用一个DP的二维数组,DP[ i ][ j ] i 代表杀怪数 , j 代表耐久度 。因为每个怪可以打多次,所以
Pack函数里的循环是顺序的。
View Code
1 #include<iostream> 2 using namespace std; 3 4 const int maxn = 100 + 10; 5 int DP[maxn][maxn]; 6 int n; 7 int m; 8 int k; 9 int s; 10 11 int max(int a,int b) 12 { 13 return a > b ? a : b; 14 } 15 16 void Pack(int cost,int weight) 17 { 18 int i; 19 int j; 20 for(i=1; i<=s; i++) 21 { 22 for(j=cost; j<=m; j++) 23 { 24 DP[i][j] = max(DP[i][j] , DP[i-1][j-cost]+weight); 25 } 26 } 27 } 28 29 int main() 30 { 31 while(cin>>n>>m>>k>>s) 32 { 33 int i; 34 int worth[maxn]; 35 int heavy[maxn]; 36 memset(DP,0,sizeof(DP)); 37 for(i=1; i<=k; i++) 38 { 39 cin>>worth[i]>>heavy[i]; 40 } 41 for(i=1; i<=k; i++) 42 { 43 Pack(heavy[i],worth[i]); 44 } 45 46 int flag = 0; 47 for(i=1; i<=m; i++) 48 { 49 if(DP[s][i]>=n) 50 { 51 cout<<m-i<<endl; 52 flag = 1; 53 break; 54 } 55 } 56 if(!flag) 57 { 58 cout<<-1<<endl; 59 } 60 } 61 return 0; 62 }

浙公网安备 33010602011771号