Coins
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3969 Accepted Submission(s): 1578
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
题意:给面值不同,有固定个数的硬币,能有多少种不同的不同总面值的组合方式;
思路:把多重背包问题用二进制拆分成 01 背包求解,再加上一点剪枝;
先解释一下多重背包如何优化,这里有一个数学的结论: 1到n以内的数字,能够通过 n 内的进制数组合得到,比如 9以内的二进制数有 1 2 4 8,可以自己在草稿纸上试一下, 3能通过 1 + 2 得到,5能通过1 + 4 得到,6能通过 2 + 4得到,所以,我们可以利用二进制数的拆分求出所有 n 以内的数;下面是拆分的过程:
9 - 1 = 8; 8 - 2 = 6; 6 - 4 = 2 ; 2 - 8 < 0; 那么要求的 9 以内的二进制数就是 1,2, 4,2,这几个二进制是能够组成 9以内包括 9 的所有整数,然后通过 w[ i ] 乘以这些二进制数,把他们当作一件物品来做01背包的处理,当然,如果没有用二进制拆分的话,可以直接把9拆分成 1,2,3,4,5,6,7,8,9 然后乘以w[ i ] 当作一件物品来做01背包处理,这种依次拆分的时间复杂度和不拆直接用多重背包处理是一样的,但是,为什么9个数字,只需要1,2,4,2这四个二进制数就够了呢?(这个问题暂时还没办法解决,能力有限,目前只要知道,只要拆分的二进制数