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

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 coins he receives in change is minimized. Help him to determine what this minimum number is.
FJ wants to buy T (1 ≤ T ≤ 10,000) cents of supplies. The currency system has N (1 ≤ N ≤ 100) different coins, with values V1, V2, ..., VN (1 ≤ Vi ≤ 120). Farmer John is carrying C1 coins of value V1, C2 coins of value V2, ...., and CN coins of value VN (0 ≤ Ci ≤ 10,000). The shopkeeper has an unlimited supply of all the coins, and always makes change in the most efficient manner (although Farmer John must be sure to pay in a way that makes it possible to make the correct change).
Input
Line 1: Two space-separated integers: N and T.
Line 2: N space-separated integers, respectively V1, V2, ..., VN coins (V1, ...VN)
Line 3: N space-separated integers, respectively C1, C2, ..., CN
Output
Line 1: A line containing a single integer, the minimum number of coins involved in a payment and change-making. If it is impossible for Farmer John to pay and receive exact change, output -1.
Sample Input
3 70
5 25 50
5 2 1
Sample Output
3

题目大意:

    FJ同学去买东西,东西的价值为T,他和卖家都有N种金币,FJ希望交易完成时金币变化最小。

    求最少的金币变化数量。FJ的金币个数有限,奸商的金币数目无限。

结题思路:

    背包问题,FJ的每种金币个数有限可以看做是多重背包问题,奸商的金币数目无限可以看做是完全背包问题。

    设F1[i]为FJ付款为i时的最小金币数,设F2[i]为奸商找钱为i时的最小金币数。

    则F1[i+T]+F2[i]就是所求的最小金币变化数量。(F1用多重背包求解,F2用完全背包求解)

    PS:这里的背包求得是最小价值,且要恰好装满。故初始化数组时应 F[0]=0,F[1-MAXN]=INT_MAX;(好久没做背包了,下意识把F[1]=0了,结果T==1时总是输出0,查了好久。。。)

Code:

 1 #include<string>
 2 #include<iostream>
 3 #include<stdio.h>
 4 #include<cstring>
 5 #include<limits.h>
 6 #define MAXN 1000000
 7 #define INF 9999999 //背包被调 直接抄的背包九讲,因为有两个数组,增加一个数组参数
 8 using namespace std;
 9 int N,V,c[MAXN+10],a[MAXN+10],w=1,f1[MAXN+10],f2[MAXN+10];
10 int min(int a,int b)
11 {
12     return a>b?b:a;
13 }
14 void ZeroOnePack(int cost,int weight,int f[]) //01背包
15 {
16     for (int v=V; v>=cost; v--)
17         f[v]=min(f[v],f[v-cost]+weight);
18 }
19 void CompletePack(int cost,int weight,int f[]) //完全背包
20 {
21     for (int v=cost;v<=V;v++)
22         f[v]=min(f[v],f[v-cost]+weight);
23 }
24 void MultiplePack(int cost,int weight,int amount,int f[]) //多重背包
25 {
26     if (cost*amount>=V)
27     {
28         CompletePack(cost,weight,f);
29         return ;
30     }
31     int k=1;
32     while (k<amount)
33     {
34         ZeroOnePack(k*cost,k*weight,f);
35         amount=amount-k;
36         k*=2;
37     }
38     ZeroOnePack(amount*cost,amount*weight,f);
39 }
40 void init(int M,int f[])
41 {
42     f[0]=0; //保证背包装满 具体原因参见背包九讲
43     for (int i=1; i<=M; i++) //求最小价值要把初值赋值为正无穷(INT_MAX可能会导致整型溢出)
44         f[i]=INF;
45 }
46 int main()
47 {
48     while (cin>>N>>V)
49     {
50
51         int V2=V;
52         int max=0;
53         for (int i=1; i<=N; i++){
54             cin>>c[i];
55             if (c[i]>max) max=c[i];}
56         for (int i=1; i<=N; i++)
57             cin>>a[i];
58         V=max*max+V2+10; //要找钱,V要比T大很多才行
59         init(V,f1);
60         init(V,f2);
61         for (int i=1;i<=N;i++)
62             MultiplePack(c[i],1,a[i],f1);
63         for (int i=1;i<=N;i++)
64             CompletePack(c[i],1,f2);
65         int ans=INF;
66         for (int i=0;i<=V-V2;i++)
67             if (f1[i+V2]!=INF&&f2[i]!=INF) ans=min(ans,f1[i+V2]+f2[i]);
68         if (ans!=INF) printf("%d\n",ans); //ans==INF表示数据没有变过,则表示无解
69         else printf("-1\n");
70     }
71     return 0;
72 }

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

时间: 2024-08-27 04:10:27

POJ3260——The Fewest Coins(多重背包+完全背包)的相关文章

【POJ3260】The Fewest Coins 多重背包+完全背包

A来B处买东西,价值M元,有N种钱,每种钱A有一定数量,而B有无限数量. 求最少用多少张钞票可以满足交易,比如样例,A出50+25,B找5,即可满足,需要3张. A用多重背包转移状态,B用完全背包. 本文的多重背包优化用的是O(n)算法,二进制转换的O(nlogn)实在懒得写了. 那种可以看http://blog.csdn.net/vmurder/article/details/39472419 " [POJ1014]Dividing 多重背包,二进制物品拆分转01背包 " 贴代码:

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 多重背包+完全背包

题目链接:http://poj.org/problem?id=3260 给店家的钱是多重背包 dp[] 店家的找钱是完全背包 dp2[] 然后最后 其中i表示多给了多少钱 也就是需要找回多少钱 int ans = INF; ans = min(ans, dp[m+i] + dp2[i]); 是一个比较简单的思路 神坑题 看到每种货币的面值不大于120 我就觉得找钱一定不会超过119块钱结果wa到死 后来才发现不是的啊 之所以我有这种思维定式是因为现实生活中有1块钱这种货币单位 考虑一种极限的情况

POJ-3260 The Fewest Coins

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

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

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

POJ 1742 Coins (多重背包)

Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 28448   Accepted: 9645 Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box and found there were some

POJ 1742 Coins 多重背包单调队列优化

http://poj.org/problem?id=1742 题意: 很多硬币,有价值和数量,给出一个上限,问上限内有多少种钱数可以由这些硬币组成. 分析: 好像是楼教主男人八题之一.然后学多重背包单调队列优化时看了别人的程序..所以后来写了就1A了=.= 前一篇小小总结了一下多重背包单调队列优化(http://www.cnblogs.com/james47/p/3894772.html),这里就不写了. 1 #include<cstdio> 2 #include<cstring>

混合背包(多重背包+完全背包)—— POJ 3260

对应POJ题目:点击打开链接 The Fewest Coins Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5450   Accepted: 1653 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