zoukankan      html  css  js  c++  java
  • HDU 3591 多重背包

    给出N种钱币和M

    给出N种钱币的面值和个数

    NPC拿着这N些钱币去买价值M的物品,能够多付。然后被找零,找零的钱也为这些面值。但没有数量限制

    问最少经手的钱币数量


    对于NPC做一个付款多重背包

    然后对于找零做一个全然背包

     ans=Min(dp1[i]+dp2[i-m],ans);


    #include "stdio.h"
    #include "string.h"
    
    
    int n,m;
    int dp1[20010],dp2[20010],c[20010],v[20010];
    void onezero_pack(int v,int k)
    {
        int i;
        for (i=20000;i>=v;i--)
            if (dp1[i-v]!=-1 && (dp1[i-v]+k<dp1[i] || dp1[i]==-1) )
            dp1[i]=dp1[i-v]+k;
    }
    
    void complete_pack(int v)
    {
        int i;
        for (i=v;i<=20000;i++)
            if (dp1[i-v]!=-1 && (dp1[i-v]+1<dp1[i] || dp1[i]==-1) )
            dp1[i]=dp1[i-v]+1;
    }
    
    void multiple_pack(int v,int c)
    {
        int k;
        if (v*c>=20000)
            complete_pack(v);
        else
        {
            k=1;
            while (k<c)
            {
                onezero_pack(k*v,k);
                c-=k;
                k*=2;
            }
            if (c>0) onezero_pack(c*v,k);
        }
    }
    
    int Min(int a,int b)
    {
        if (a<b) return a;
        else return b;
    }
    int main()
    {
        int Case,i,j,ans;
        Case=0;
        while (scanf("%d%d",&n,&m)!=EOF)
        {
            if (n+m==0) break;
            for (i=1;i<=n;i++)
                scanf("%d",&v[i]);
            for (i=1;i<=n;i++)
                scanf("%d",&c[i]);
    
            memset(dp1,-1,sizeof(dp1));
            dp1[0]=0;
    
    
            for (i=1;i<=n;i++)
                multiple_pack(v[i],c[i]);
    
           memset(dp2,-1,sizeof(dp2));
            dp2[0]=0;
            for (i=1;i<=n;i++)
                for (j=0;j<=20000-v[i];j++)
                {
                    if (dp2[j]!=-1 && (dp2[j]+1<dp2[j+v[i]] || dp2[j+v[i]]==-1) )
                        dp2[j+v[i]]=dp2[j]+1;
                }
    
            ans=0x3f3f3f3f;
            for (i=m;i<=20000;i++)
                if (dp1[i]!=-1 && dp2[i-m]!=-1)
                    ans=Min(dp1[i]+dp2[i-m],ans);
    
            printf("Case %d: ",++Case);
            if (ans==0x3f3f3f3f)
                printf("-1
    ");
            else
                printf("%d
    ",ans);
        }
        return 0;
    }
    



  • 相关阅读:
    Jmeter之CSV文件读取
    性能计数器及性能分析方法
    性能测试的应用领域
    动态加载JS文件方法总结
    handler method 参数绑定常用注解
    A4纸网页打印
    page-break-before和page-break-after 实现分页打印
    $.ajax 中的contentType
    @Controller和@RestController的区别?
    web页面内容打印总结
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6747613.html
Copyright © 2011-2022 走看看