Problem T
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 16 Accepted Submission(s) : 3
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.<br><br>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
题目要求:告诉你钱的种类和数目,然后他买的物品价值不会超过m,让你求出不兑钱的情况下可能的m以内的可支付价种类数。
解题思路:可以用背包问题进行解决,将m看成背包容积,但求得的解释d[v]下是否能够完全分配,即判断d[v]是否等于v,将各个物品进行完全背包循环后进行判断,若d[v]==v,则flag++最终输出flag即可。
解题代码:
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
int d[100005],w[110],q[110];
int n,m;
void ZeroOnePack(int c, int w)
{
for (int v = m; v >= c; v--)
{
d[v] = max(d[v], d[v-c] + w);
}
}
void CompletePack(int c, int w)
{
for (int v = c; v <= m; v++)
{
d[v] = max(d[v], d[v-c] + w);
}
}
//多重背包,二进制。
void MultiplePack(int c, int w, int n1)
{
if (c * n1 >= m)
{
CompletePack(c, w);
}
else
{
int k = 1;
while (k < n1)
{
ZeroOnePack(k*c, k*w);
n1 -= k;
k <<= 1;
}
ZeroOnePack(n1*c, n1*w);
}
}
int main()
{
int i,j;
while(cin>>n>>m)
{
memset(d,0,sizeof(d));
if(n==0&&m==0)break;
for(i=1;i<=n;i++)
cin>>w[i];
for(i=1;i<=n;i++)
cin>>q[i];
for(i=1;i<=n;i++)
MultiplePack(w[i],w[i],q[i]);
int flag=0;
for(i=1;i<=m;i++)
if(d[i]==i)flag++;
cout<<flag<<endl;
}
}