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 V 1, V 2, ..., VN coins ( V 1, ... VN)
Line 3: N space-separated integers, respectively C 1, C 2, ..., 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
Hint
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 V 1, V 2, ..., VN coins ( V 1, ... VN)
Line 3: N space-separated integers, respectively C 1, C 2, ..., 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
Hint
Farmer John pays 75 cents using a 50 cents and a 25 cents coin, and receives a 5 cents coin in change, for a total of 3 coins used in the transaction.
题意:给出硬币的种类,物品的价格,商店有那些种类的硬币无数个,而你拥有有限个硬币,在支付和找钱的过程中一共最少需要多少种硬币。
思路:题目分为支付和找钱,可以看出支付的时候为多重背包,找钱的时候为完全背包
多重背包,但是背包是求最少有多少种,这就和平时的背包不一样了,平时的背包是最多,那么在max的位置转换成min就可以了,此题目的背包重量:maxw*maxw+m(求解方法:https://www.cnblogs.com/ACMan/archive/2012/08/14/2637437.html,也可以把数组开大即可),硬币的面值为重量,价值为1,因为此题目是求种类,所以每种硬币的价值都是一样的都是1
完全背包:套模板即可
2个背包开2个数组,在计算硬币种类详情看代码
#include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <set>
using namespace std;
typedef long long ll;
#define INF 1<<29
int m,n,maxn;
int w[105],c[105];
int dp[25000];//dp[]买家的硬币种类
int f[25000]; //f[]售货员的硬币种类
void ZeroOnePack(int w,int v)
{
for(int i=maxn;i>=w;i--)
dp[i]=min(dp[i],dp[i-w]+v);
// printf("01 %d\n",dp[maxn]);
}
void CompletePack(int w,int v)
{
for(int i=w;i<=maxn;i++)
dp[i]=min(dp[i],dp[i-w]+v);
// printf("con %d\n",dp[maxn]);
}
void MultiplePack(int w,int v,int cnt)
{
//printf("%d %d %d %d \n",w,v,cnt,maxn);
if(cnt*w>=maxn) //物品无限的完全背包
{
CompletePack(w,v);
return ;
}
else{
int k=1; //否则进行0-1背包转化
while(k<cnt){
ZeroOnePack(k*w,k*v);
cnt-=k;
k=k*2;
}
ZeroOnePack(cnt*w,cnt*v);
return ;
}
}//完全背包模板
int main()
{
while(~scanf("%d%d",&n,&m))
{
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; //得到maxnn
fill(dp,dp+maxn+1,INF); //把dp[0]~dp[maxn]赋值INF
fill(f,f+maxn+1,INF);
dp[0]=0; f[0]=0;
for(int i=1;i<=n;i++)
MultiplePack(w[i],1,c[i]);
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; //不能找出,调整输出为-1.
printf("%d\n",ans);
}
return 0;
}

本文介绍了如何解决一个与硬币找零有关的数学问题。当支付和找零涉及到多种硬币时,如何使用最少的硬币种类进行交易。问题转化为多重背包与完全背包的组合,通过转换max到min来解决多重背包问题,完全背包部分则直接套用模板。文章提供了详细思路和代码实现。
1919

被折叠的 条评论
为什么被折叠?



