多重背包问题,利用背包的二进制即可解决
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 }