• The trouble of Xiaoqian_多重背包&&完全背包


    Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
    Total Submission(s) : 28   Accepted Submission(s) : 12

    Font: Times New Roman | Verdana | Georgia

    Font Size: ← →

    Problem Description

    In the country of ALPC , Xiaoqian is a very famous mathematician. She is immersed in calculate, and she want to use the minimum number of coins in every shopping. (The numbers of the shopping include the coins she gave the store and the store backed to her.)
    And now , Xiaoqian wants to buy T (1 ≤ T ≤ 10,000) cents of supplies. The currency system has N (1 ≤ N ≤ 100) different coins, with values V1, V2, ..., VN (1 ≤ Vi ≤ 120). Xiaoqian is carrying C1 coins of value V1, C2 coins of value V2, ...., and CN coins of value VN (0 ≤ Ci ≤ 10,000). The shopkeeper has an unlimited supply of all the coins, and always makes change in the most efficient manner .But Xiaoqian is a low-pitched girl , she wouldn’t like giving out more than 20000 once.

    Input

    There are several test cases in the input.
    Line 1: Two space-separated integers: N and T. 
    Line 2: N space-separated integers, respectively V1, V2, ..., VN coins (V1, ...VN) 
    Line 3: N space-separated integers, respectively C1, C2, ..., CN
    The end of the input is a double 0.

    Output

    Output one line for each test case like this ”Case X: Y” : X presents the Xth test case and Y presents the minimum number of coins . If it is impossible to pay and receive exact change, output -1.

    Sample Input

    3 70
    5 25 50
    5 2 1
    0 0
    
    

    Sample Output

    Case 1: 3

    一个人拿>=t的钱去买价值为t的东西,给出了拿的钱的面值和数量,用多重背包处理加上二进制优化就可以解决了。

    商家找钱,>t时商家要找钱i-t,商家的钱的数量视为无限,用完全背包,最后人和商家的交易中钱的数量最少的情况。

    dp[i]=k;i表示当前钱的金额,k表示构成当前金额目前为止需要的最少钱的数量。

    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    using namespace std;
    #define inf 0x7777777
    const int maxn=20000;
    const int N=150;
    int v[N],c[N];
    int dp1[maxn+1],dp2[maxn+1];
    int min(int a,int b)
    {
        return a<b?a:b;
    }
    void onepack(int a,int w)
    {
        a=a*w;
        for(int i=maxn;i>=a;i--)
        {
            dp2[i]=min(dp2[i],dp2[i-a]+w);
        }
    }
    void allpack(int a)
    {
        for(int i=a;i<=maxn;i++)
        {
            dp2[i]=min(dp2[i],dp2[i-a]+1);
        }
    }
    void mulpack(int a,int w)
    {
        if(a*w>=maxn)
        {
            allpack(a);
            return ;
        }
        int cnt=1;
        while(cnt<w)
        {
            onepack(a,cnt);
            w-=cnt;
            cnt*=2;
        }
        onepack(a,w);
    }
    
    int main()
    {
        int n,t;
        int cas=0;
        while(cin>>n>>t,n||t)
        {
            cas++;
    
            for(int i=1; i<=n; i++)
                cin>>v[i];
            for(int j=1; j<=n; j++)
                cin>>c[j];
    
            for(int i=1; i<=20000; i++)
                dp2[i]=inf,dp1[i]=inf;//我刚开始直接用memset,答案一直不对,长记性!!
            dp2[0]=0,dp1[0]=0;
            for(int i=1; i<=n; i++)
                for(int j=v[i]; j<=maxn; j++)
                {
                    dp1[j]=min(dp1[j],dp1[j-v[i]]+1);
                }
            for(int i=1;i<=n;i++)
            {
                mulpack(v[i],c[i]);
            }
            int ans=inf;
            for(int i=t;i<=20000;i++)
            {
                if(dp2[i]!=inf&&dp1[i-t]!=inf)
                    ans=min(ans,dp1[i-t]+dp2[i]);//dp1表示商家,dp2表示人,最后自己没注意,wa了好几次;
            }
            cout<<"Case "<<cas<<": ";
            if(ans==inf) cout<<"-1"<<endl;
            else cout<<ans<<endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    大教堂和市集
    VB相关资源
    什么样的团队才是优秀的团队
    走过2007
    一种简单实用的错误码构建方法
    熊的困惑
    调测中的反思
    PowerPC852T的SMC初始化—串口通信
    Silverlight Listbox 取消全选的方法
    电脑读不出U盘,有一个黄色感叹号的解决方法
  • 原文地址:https://www.cnblogs.com/iwantstrong/p/5735562.html
Copyright © 2020-2023  润新知