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 }

 

posted @ 2012-09-13 11:04  pc....  阅读(303)  评论(0)    收藏  举报