• POJ 3260 The Fewest Coins(背包问题)


    【题目链接】 http://poj.org/problem?id=3260

    【题目大意】

      给出你拥有的货币种类和每种的数量,商店拥有的货币数量是无限的,
      问你买一个价值为m的物品,最少的货币流通数量为多少

    【题解】

      我们可以计算出买不同价值的物品,在没有找钱情况下的最少用币数量,
      记为dp[i],这个可以用多重背包来完成,对于商店来说,我们可以计算出,
      对于不同额度的找零,最少用币数量,记为f[i],
      我们发现,对于货币流通最少,就是求dp[i+m]+f[i]的最小值,
      由鸽巢原理可得我们只要计算maxw*maxw+m的dp值就可以了。

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int INF=0x3f3f3f3f;
    int m,n,w[110],c[110],dp[24563],f[24563]; 
    int main(){
        while(~scanf("%d%d",&n,&m)){
            int maxn=0;
            for(int i=1;i<=n;i++)scanf("%d",&w[i]),maxn=max(maxn,w[i]);
            for(int i=1;i<=n;i++)scanf("%d",&c[i]);
            maxn=maxn*maxn+m+1;
            memset(dp,INF,sizeof(dp));
            dp[0]=0;
            for(int i=1;i<=n;i++){
                if(c[i]*w[i]>=maxn){
                    for(int j=w[i];j<=maxn;j++)dp[j]=min(dp[j],dp[j-w[i]]+1);
                }else{
                    for(int k=1;k<c[i];k<<=1){
                        for(int j=maxn;j>=w[i]*k;j--)dp[j]=min(dp[j],dp[j-w[i]*k]+k);
                        c[i]-=k;
                    }for(int j=maxn;j>=w[i]*c[i];j--)dp[j]=min(dp[j],dp[j-w[i]*c[i]]+c[i]);
                }memset(f,INF,sizeof(f));f[0]=0;
            }
            for(int i=1;i<=n;i++){
                for(int j=w[i];j<=maxn;j++)f[j]=min(f[j],f[j-w[i]]+1);
            }int ans=INF;
            for(int i=0;i<=maxn-m;i++)ans=min(ans,dp[i+m]+f[i]);
            if(ans==INF)ans=-1;
            printf("%d
    ",ans);
        }return 0;
    }
  • 相关阅读:
    JPA-基本注解
    响应式、自适应式
    Spring boot传值注意事项
    Angular与Vue
    Java 时间转换
    SpringBoot 上传读取图片 巨坑
    前后端分离之 文件上传
    System.nanoTime与System.currentTimeMillis
    sqlserver 新增子段有默认值
    json转换
  • 原文地址:https://www.cnblogs.com/forever97/p/poj3260.html
Copyright © 2020-2023  润新知