1020 of dp


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;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值