[USACO06DEC]最少的硬币The Fewest Coins

题目描述

约翰在镇上买了 T 元钱的东西,正在研究如何付钱。假设有 N 种钞票,第 i 种钞票的面值为 Vi,约翰身上带着这样的钞票 Ci 张。商店老板罗伯是个土豪,所有种类的钞票都有无限张。他们有洁癖,所以希望在交易的时候,交换的钞票张数尽可能地少。请告诉约翰如何恰好付掉 T 元,而且在过程中交换的货币数量最少。

输入格式

? 第一行:两个整数 N 和 T,1 ≤ N ≤ 100, 1 ≤ T ≤ 10000

? 第二行:n个整数 Vi 第三行:n个整数 Ci,1 ≤ Vi ≤ 120, 0 ≤ Ci ≤ 10000

输出格式

单个整数:表示付钱找零过程中交换的最少货币数量,如果约翰的钱不够付账,或老板没法找 开零钱,输出 ?1。

样例输入

3 70

5 25 50

5 2 1

样例输出

3

【题目 https://www.luogu.org/problemnew/show/2851】(蒟蒻不会弄链接,望大佬指点orz)

题解

易证,要求交换的货币数量最少,那么约翰付给罗伯的货币数最少,罗伯找给约翰的货币也最少。不妨分开来算。

设约翰身上总共有tot元钱,那么罗伯最多找给约翰tot-T元钱。现在我们知道罗伯有哪几种面值的钞票,以及他最多需要用这些钞票凑出的总额,而每种面值的钞票都有无限张,我们就可以求出罗伯凑出1~(tot-T)元钱分别需要的最少的货币数。这就是完全背包。

解决了罗伯,约翰也就比较简单了。

同样的,我们知道约翰有哪几种面值的钞票,以及每种钞票的数量,显然,约翰最多可以付tot元,和解决罗伯的方法类似,我们可以求出约翰凑出1~tot元钱分别需要的最少的货币数。多重背包出现了……

由于数据较大,多重背包要有二进制优化。否则会TLE!

还有,由于这两个背包都要恰好装满,要把数组初始化为无穷大。

最后,枚举约翰付的钱数,计算约翰需要付的最少货币数和罗伯需要找的最少货币数之和,求最小值。

#include <cstdio>
int n,T,w[105],c[105],v[1000005],g[1000005],f[1000005],t,tot,maxw;
const int inf=1e9;
int min(int x,int y)
{
    return x<=y?x:y;
}
int main()
{
    int i,j,k;
    scanf("%d%d",&n,&T);
    for (i=1;i<=n;i++)
      scanf("%d",&w[i]);
    for (i=1;i<=n;i++)
    {
        scanf("%d",&c[i]);
        tot+=w[i]*c[i];
        if (w[i]>maxw) maxw=w[i];
    }
    if (tot<T)
    {
        printf("-1");
        return 0;
    }
    maxw=(maxw*maxw+T);
    for (i=1;i<1000005;i++)
      g[i]=f[i]=inf;
    for (i=1;i<=n;i++)
      for (j=w[i];j<=maxw;j++)
        g[j]=min(g[j],g[j-w[i]]+1);
    for (i=1;i<=n;i++)
    {
        for (j=1;j<=c[i];j<<=1)
        {
            for (k=maxw;k>=j*w[i];k--)
              f[k]=min(f[k],f[k-j*w[i]]+j);
            c[i]-=j;
        }
        if (c[i])
          for (j=maxw;j>=c[i]*w[i];j--)
            f[j]=min(f[j],f[j-c[i]*w[i]]+c[i]);
    }
    int ans=inf;
    for (i=T;i<=maxw;i++)
      ans=min(ans,f[i]+g[i-T]);
    if (ans<inf) printf("%d",ans);
    else printf("-1");
    return 0;
} 
时间: 2024-08-30 13:09:49

[USACO06DEC]最少的硬币The Fewest Coins的相关文章

洛谷P2851 [USACO06DEC]最少的硬币The Fewest Coins(完全背包+多重背包)

题目描述 Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the smallest number of coins changes hands, i.e., the number of coins he uses to pay plus the number of coins he

POJ 3260 The Fewest Coins 最少硬币个数(完全背包+多重背包,混合型)

题意:FJ身上有各种硬币,但是要买m元的东西,想用最少的硬币个数去买,且找回的硬币数量也是最少(老板会按照最少的量自动找钱),即掏出的硬币和收到的硬币个数最少. 思路:老板会自动找钱,且按最少的找,硬币数量也不限,那么可以用完全背包得出组成每个数目的硬币最少数量.而FJ带的钱是有限的,那么必须用多重背包,因为掏出的钱必须大于m,那么我们所要的是大于等于m钱的硬币个数,但是FJ带的钱可能很多,超过m的很多倍都可能,那么肯定要有个背包容量上限,网上说的根据抽屉原理是m+max*max,这里的max指

POJ3260The Fewest Coins[背包]

The Fewest Coins Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6299   Accepted: 1922 Description Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the sm

POJ3260——The Fewest Coins(多重背包+完全背包)

The Fewest Coins DescriptionFarmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the smallest number of coins changes hands, i.e., the number of coins he uses to pay plus

有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?

可以用DP 方法去解: coins_count[x], 表示已知x元, 可以最少用 coins_count[x] 个硬币来凑出来. coins_count[x] = min{ coins_count[x - 1] + 1,   coins_count[x - 3] + 1, coins_count[x - 5] + 1} coins_count[11] 表示的数目的等于 : coins_count[10] , coins_count[8], coins_count[6] 中的最小值, 加 1.

poj3260 The Fewest Coins

Description Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the smallest number of coins changes hands, i.e., the number of coins he uses to pay plus the number of co

POJ 3260 The Fewest Coins(多重背包+全然背包)

http://poj.org/problem?id=3260 题意: John要去买价值为m的商品. 如今的货币系统有n种货币,相应面值为val[1],val[2]-val[n]. 然后他身上每种货币有num[i]个. John必须付给售货员>=m的金钱, 然后售货员会用最少的货币数量找钱给John. 问你John的交易过程中, 他给售货员的货币数目+售货员找钱给他的货币数目 的和最小值是多少? 分析: 本题与POJ 1252类型: http://blog.csdn.net/u013480600

POJ-3260 The Fewest Coins

题目链接:POJ-3260 题意是一个人买东西,有n种纸币,面额为v[i],数量为c[i].同时售货员也有这些纸币,数量为无限.要买价值为t的东西,希望给"钱用的纸币数和着钱用的纸币数的和"最少. 思路很显然是完全背包和多重背包各处理售货员和这位老哥.这个题给出所有v[i]<=120,这一点很有迷惑性. 一开始我的做法是把上界设成t+120,但是发现这样的做法是不多的.网上给出的做法是设上界为maxv*maxv+t.证明过程如下: 要凑足(大于等于)价格T的商品且硬币数最少,最多

POJ3260——背包DP(多重)——The Fewest Coins

Description Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the smallest number of coins changes hands, i.e., the number of coins he uses to pay plus the number of co