HDU 2844

来源:互联网 发布:淘宝收货姓名写什么好 编辑:程序博客网 时间:2024/04/28 19:49

Coins
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9826 Accepted Submission(s): 3916

Problem Description

Whuacmers use coins.They have coins of value A1,A2,A3…An Silverland dollar. One day Hibix opened purse and found there were some coins. He decided to buy a very nice watch in a nearby shop. He wanted to pay the exact price(without change) and he known the price would not more than m.But he didn’t know the exact price of the watch.

You are to write a program which reads n,m,A1,A2,A3…An and C1,C2,C3…Cn corresponding to the number of Tony’s coins of value A1,A2,A3…An then calculate how many prices(form 1 to m) Tony can pay use these coins.

Input

The input contains several test cases. The first line of each test case contains two integers n(1 ≤ n ≤ 100),m(m ≤ 100000).The second line contains 2n integers, denoting A1,A2,A3…An,C1,C2,C3…Cn (1 ≤ Ai ≤ 100000,1 ≤ Ci ≤ 1000). The last test case is followed by two zeros.

Output

For each test case output the answer on a single line.

Sample Input

3 10
1 2 4 2 1 1
2 5
1 4 2 1
0 0

Sample Output

8
4

多重背包的典型例题,在其中有几点值得思考
1.如果一个物品的数目乘以价值已经超过最大的m,那么此时可以看作是完全背包。

2.1如果一个物品的数目乘以价值没有超过最大的m,那么此时用二进制拆分后用01背包。
2.2二进制拆分不是很理解怎么来的。 。记住了结论。 。13可以拆成1,2,4,6.这四个数中取一些数可以组成1到13的所有整数。

3.最后判断dp[i] == i因为刚好这题是一维的。 。重量和价值是一样的。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>//#define LOCALusing namespace std;int a[120];int b[120];int dp[100020];int n,m;void MultiplePack(int value,int number);void ZeroOnePack(int value);void ComletePack(int value);int main(){#ifdef LOCAL    freopen("data.in","r",stdin);    freopen("data.out","w",stdout);#endif // LOCAL    while(scanf("%d%d",&n,&m)&&(n!=0||m!=0)){        int i,j;        for(i = 0;i<n;i++)            scanf("%d",&a[i]);        for(i = 0;i<n;i++)            scanf("%d",&b[i]);        memset(dp,0,sizeof(dp));        int k;        for(i = 0;i<n;i++)            MultiplePack(a[i],b[i]);        int sum = 0;        for(i = 1;i<=m;i++)            if(i == dp[i])                sum++;        printf("%d\n",sum);    }    return 0;}//完全背包void ComletePack(int value){    for(int i = value;i<=m;i++)        dp[i] = max(dp[i],dp[i-value]+value);}//01背包void ZeroOnePack(int value){    for(int i = m;i>=value;i--)        dp[i] = max(dp[i],dp[i-value]+value);}//多重背包void MultiplePack(int value,int number){    if(value*number>=m)        ComletePack(value);    else{        int k = 1;        while(k<number){            ZeroOnePack(k*value);            number -= k;            k<<=1;        }        ZeroOnePack(number*value);    }}
0 0