HDU2844 Coins 背包

多重背包问题,利用背包的二进制即可解决

 1 /*
 2 写于13年2月28日
 3 多重背包的二进制写法
 4 */
 5 
 6 #include <iostream>
 7 #include <stdio.h>
 8 #include <math.h>
 9 #include <string.h>
10 using namespace std;
11 
12 int n,m;
13 
14 struct {
15     int value;//硬币的价值以及数量
16     int number;
17 }data[105];
18 int bag[100005];//bag[i]表示容积不超过i时装的最大钱数,钱数为i时正好相等
19 //完全背包
20 void full_bag(int value)
21 {
22     for(int i=value;i<=m;i++)
23         bag[i]=max(bag[i],bag[i-value]+value);
24 }
25 //01背包
26 void zeroone_bag(int value)
27 {
28     for(int i=m;i>=value;i--)
29         bag[i]=max(bag[i],bag[i-value]+value);
30 }
31 int main()
32 {
33     while(scanf("%d%d",&n,&m)!=EOF)
34     {
35         //scanf("%d%d",&n,&m);
36         if(!n&&!m)
37             break;
38         memset(bag,0,sizeof(bag));//背包清零
39         for(int i=1;i<=n;i++)
40             scanf("%d",&data[i].value);
41         for(int i=1;i<=n;i++)
42             scanf("%d",&data[i].number);
43         for(int i=1;i<=n;i++)
44         {
45             if(data[i].value*data[i].number>m)
46                 full_bag(data[i].value);
47             else
48             {
49                 int k=1;
50                 while(data[i].number>=k)
51                 {
52                     data[i].number-=k;
53                     zeroone_bag(k*data[i].value);
54                     k=k<<1;
55                 }
56                 zeroone_bag(data[i].number*data[i].value);
57             }
58 
59         }
60         int num=0;
61         //bag[i]=i时表示容积为i的背包恰好装(满)i大小的钱数
62         for(int i=1;i<=m;i++)
63             if(bag[i]==i)
64                 num++;
65         printf("%d\n",num);
66     }
67 
68     return 0;
69 }

 

posted on 2013-02-28 21:14  行者1992  阅读(151)  评论(0编辑  收藏  举报