zoukankan      html  css  js  c++  java
  • POJ3260 完全背包 + 多重背包 xingxing在努力

      这道题的意思是一个人有一定数额的银币若干个, 想用这些硬币买一些东西, 售货员会找零,现在问你如何用最少的银币买到东西。。。 先用完全背包预处理找零j块钱的时候最少需要多少硬币,然后用多重背包处理付款j块钱的时候最少需要多少银币, 最后将两个加起来就行。注意数组开大点。代码如下:

      

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    const int inf = 0x3f3f3f3f;
    int N, T;
    int V[100 + 10];   //硬币的面额
    int C[100 + 10];   //硬币的数量
    int back[30000 + 10];              //找零为j是需要的最少的银币的数量
    int f[30000 + 10];                 //付款为j时所需要的最少的银币数量
    
    void ComplatePack(int cost, int weight)
    {
        for(int j=cost; j<=30000; j++)
            if(f[j]>f[j-cost]+weight && f[j-cost]!=inf)
                f[j] = f[j-cost] + weight;
        return ;
    }
    
    void ZeroOnePack(int cost, int weight)
    {
        for(int j=30000; j>=cost; j--)
            if(f[j]>f[j-cost]+weight && f[j-cost]!=inf)
                f[j] = f[j-cost] + weight;
        return ;
    }
    
    void MultiPack(int cost ,int weight, int number)
    {
        if(cost*number>30000)
        {
            ComplatePack(cost, weight);
            return ;
        }
        int k = 1;
        while(k < number)
        {
            ZeroOnePack(k*cost, k*weight);
            number -= k;
            k *= 2;
        }
        ZeroOnePack(number*cost, number*weight);
    }
    
    int main()
    {
        while(scanf("%d%d", &N, &T) == 2)
        {
            for(int i=0; i<N; i++)
                scanf("%d", &V[i]);
            for(int i=0; i<N; i++)
                scanf("%d", &C[i]);
            memset(back, 0x3f, sizeof(back));
            back[0] = 0;
            for(int i=0; i<N; i++)            //预处理找零为j时所需银币最少
                for(int j=V[i]; j<=30000; j++)
                    if(back[j]>back[j-V[i]]+1 && back[j-V[i]]!=inf)
                        back[j] = back[j-V[i]] + 1;
            memset(f, 0x3f, sizeof(f));
            f[0] = 0;
            for(int i=0; i<N; i++)
                MultiPack(V[i], 1, C[i]);
            int res = inf;
            for(int i=T; i<=30000; i++)
            {
                if(back[i-T]!=inf&&f[i]!=inf&&back[i-T]+f[i]<res)
                    res = back[i-T] + f[i];
            }
            if(res == inf)
                printf("-1
    ");
            else 
                printf("%d
    ", res);
        }
        return 0;
    }
  • 相关阅读:
    《C# to IL》第一章 IL入门
    multiple users to one ec2 instance setup
    Route53 health check与 Cloudwatch alarm 没法绑定
    rsync aws ec2 pem
    通过jvm 查看死锁
    wait, notify 使用清晰讲解
    for aws associate exam
    docker 容器不能联网
    本地运行aws lambda credential 配置 (missing credential config error)
    Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?
  • 原文地址:https://www.cnblogs.com/xingxing1024/p/5012750.html
Copyright © 2011-2022 走看看