zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    IdentityServer4 令牌端点
    IdentityServer4 授权端点
    IdentityServer4 发现端点
    IdentityServer4 注销端点
    IdentityServer4 自检端点
    spring boot 项目简单打包部署
    如何进阶成公司 Git 小能手
    Git常用命令参考手册
    网络面试题总结
    Nginx面试可能问到的部分
  • 原文地址:https://www.cnblogs.com/iwantstrong/p/5735562.html
Copyright © 2011-2022 走看看