zoukankan      html  css  js  c++  java
  • hdu 3591 The trouble of Xiaoqian

    hdu 3591  The trouble of Xiaoqian

    题意:xiaoqi要买一个T元的东西,当前的货币有N种,xiaoqi对于每种货币有Ci个;题中定义了最小数量即xiaoqi拿去买东西的钱的张数加上店家找的零钱的张数(店家每种货币有无限多张,且找零是按照最小的数量找零的);问xiaoqi买元东西的最小数量?

    多重背包+完全背包;

    思路:这个最小数量是拿去买东西的张数和找零的张数之和,其实我们只需要将这两个步骤分开,开算出能买T元东西的前i最少f[i]张,这里涉及到容量问题;容量只要大于T小于最大的上线20,000即可;之后使用贪心将货币排序加上找的零钱的数量,求出最小的数量即可;

    注:无解的情况分为 总的和达不到T,和当前的货币不能找开i;(i - T找零时除到了0...RE了几次);

    78MS  1668K

    #include<bits/stdc++.h>
    using namespace std;
    #define rep0(i,l,r) for(int i = (l);i < (r);i++)
    #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
    #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
    #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
    #define MS0(a) memset(a,0,sizeof(a))
    #define MS1(a) memset(a,-1,sizeof(a))
    #define inf 0x3f3f3f3f
    #define lson l, m, rt << 1
    #define rson m+1, r, rt << 1|1
    typedef __int64 ll;
    template<typename T>
    void read1(T &m)
    {
        T x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        m = x*f;
    }
    template<typename T>
    void read2(T &a,T &b){read1(a);read1(b);}
    template<typename T>
    void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
    template<typename T>
    void out(T a)
    {
        if(a>9) out(a/10);
        putchar(a%10+'0');
    }
    const int M = 20020;
    int f[M],V,n;
    int w[110],num[110];
    void ZeroOnePack(int w,int k)
    {
        for(int v = V;v >= w;v--)
            f[v] = min(f[v],f[v-w]+k);
    }
    void CompletePack(int w)
    {
        for(int v = w;v <= V;v++)
            f[v] = min(f[v],f[v-w]+1);
    }
    void MultiPack(int w,int num)
    {
        if(w*num >= V)
            CompletePack(w);
        else{
            for(int k = 1;k < num;k <<= 1){
                ZeroOnePack(w*k,k);
                num -= k;
            }
            ZeroOnePack(w*num,num);
        }
    }
    inline int change(int a)
    {
        int cnt = 0;
        for(int i = n;a;i--){
            if(w[i] == 0) return inf;
            cnt += a/w[i];
            a %= w[i];
        }
        return cnt;
    }
    int main()
    {
        int t,kase = 1;
        while(scanf("%d%d",&n,&t) == 2 && n+t){
            int sum = 0;
            rep1(i,1,n) read1(w[i]);
            rep1(i,1,n) read1(num[i]),sum += num[i]*w[i];
            V = min(sum,M-1);
            memset(f,0x3f,sizeof(f));
            f[0] = 0;
            rep1(i,1,n)
                MultiPack(w[i],num[i]);
            sort(w+1,w+n+1);
            //rep_1(i,n,1) cout<<w[i]<<" ";puts("");
            int ans = inf;
            rep1(i,t,V)if(f[i] != inf){
                f[i] += change(i-t);
                ans = min(ans,f[i]);
            }
            printf("Case %d: %d
    ",kase++,ans == inf?-1:ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    paip.51cto HTML转码规则
    常用记账软件总结
    paip.为什么软件体积越来越大
    paip.版本控制CVSSVNTFS总结
    paip.提升用户体验导入导出
    paip.手机ROOT过程总结
    PAIP.http post 400错误
    paip.javaaspphp.net互相调用方法大总结
    PAip.英文引擎在项目开发上的作用
    paip.SVN无法提交提示冲突的解决
  • 原文地址:https://www.cnblogs.com/hxer/p/5202381.html
Copyright © 2011-2022 走看看