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

      

  • 相关阅读:
    防止sql注入的小函数 以及一些小验证
    PHP几个防SQL注入攻击自带函数区别
    redis配置文件.conf和常用配置
    redis常用命令
    redis数据类型
    redis的安装和简单操作
    yum CentOS7安装mysql
    Linux安装mysql
    firewall-cmd 常用命令
    解决linux下启动tomcat找不到jdk
  • 原文地址:https://www.cnblogs.com/iwantstrong/p/5735562.html
Copyright © 2011-2022 走看看