找零问题

问题描述:

为找零问题 设计一种动态规划算法:给定金额n以及各种面额d1,d2,...,dm的数量无限的硬币,求总金额等于n的硬币的最少个数,或者指出该问题无解。

(对于该问题可以用动态规划方法或者贪婪法求解,但贪婪法要注意如何说明局部最优可以保证全局最优)

思路: 

各种硬币的面额为 d[1,2,3,..N],设C[i,j]为在前i种面额中求总面值为j的最优解(最少硬币数)。

初始化

C[i,j] = 正无穷 (i=0, j>=1 && j<=N)

c[i,j] = 0(i>=0 && i<=M ,j=0)

正无穷表示无解。

前i种面额中总价值为j可以分为以下几种情况:

不包含第i中面额的硬币...

包含1个第i中面额的硬币...

包含2个第i中面额的硬币...

...

包含k个第i中面额的硬币... (j-d[i]*k>=0)

如果总价值为j的金额包含k个第i种面额,而第i种硬币的面额值为d[i],则前i-1种硬币只需求凑齐金额为j-d[i]*k的最优解,

所以可以建立如下的递推关系:

C[i,j] = min(C[i-1,j-d[i]*k] + k) , 其中j-d[i]*k >=0

例子:

已知四种面额为4,2,3,5的硬币,求总金额等于7的硬币的最少个数。

很明显可以看出该问题中

两枚硬币的组合方式:

7=4+3,7=5+2,

三枚硬币的组合方式:

7=2+2+3

所以最少硬币数为2

下面利用动态规划算法求解最少硬币数。

#include <iostream>
#include <iomanip>

const int M = 4;
const int N =7;
const int KIND = 4;
const int MAX_INIFINITE = 10000;
int c[M+1][N+1];

using namespace std;

int d[KIND + 1] = {0,4,2,3,5};
int findmoney(int i,int j);
int min(int x,int y);

int main()
{

	int i;
	int j;

	for(i = 0;i<=M;i++)
		for(j = 0;j<=N;j++)
			c[i][j] = MAX_INIFINITE;

	for(i = 0;i<=M;i++)
		c[i][0] = 0;

	//call
	c[M][N] = findmoney(M,N);//

	if(c[M][N] < MAX_INIFINITE)
		cout << "总金额为" << N << ",则至少需要的硬币个数为:" << c[M][N] << endl;
	else
		cout << "No answer" << endl;

	for(int i = 0;i<=M;i++)
	{
		for(int j = 0;j<=N;j++)
		{
			cout << setw(8) << setiosflags(ios::left);
			cout << c[i][j] << " ";
		}
		cout << endl;
	}
	return 0;
}

int findmoney(int i,int j)
{
	int k = 0;
	int value = MAX_INIFINITE;
	if(i + j >=2)//除去第一行和第一列
	{
		while(j - d[i]*k >=0 && i>=1)
		{
			value = min(findmoney(i-1,j-d[i]*k)+k,value);
			k++;//
		}
		c[i][j] = value;
	}

	return c[i][j];

}

int min(int x,int y)
{
	return x<y?x:y;
}

分析输出矩阵C[M+1][N+1]可以知道,从上图中绿色下划线标记可以知道,通过自顶向下的方式计算C[4][7]的值,仅需要知道C[1,4],C[2,2],C[2,4],C[3,2],C[3,7]

同样的。如果N = 1,则输出"No answer"

附:网上搜集的与找零问题相关的具体问题的解答:

找零问题有解及其面值组成

动态规划求解硬币找零问题

上面两篇章文章给出的方案和算法中能求出有解的情况,并给出具体应该是哪几个面值的硬币,而且面值中含有面额为1的硬币。对无解的情况没有处理。

找零问题 完全背包

该文讨论的是凑齐给定金额的方式有几种。

找零问题,布布扣,bubuko.com

时间: 2024-10-20 17:25:31

找零问题的相关文章

18-硬币找零

/*                                     硬币找零 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述    在现实生活中,我们经常遇到硬币找零的问题,例如,在发工资时,财务人员就需要计算最少的找零硬币数,以便他们能从银行拿回最少的硬币数,并保证能用这些硬币发工资.    我们应该注意到,人民币的硬币系统是 100,50,20,10,5,2,1,0.5,0.2,0.1,0.05,    0.02,0.01 元,采用这些硬币我们可以对任

张书乐:抢夺万亿市场,BAT布局跨境支付打响“找零”战争

数据显示,2016年中国跨境电商进出口额预计将增至6.5万亿元(1.02万亿美金),达到30%的年增长率,占中国总进出口贸易额的20%.另外,在签证政策等利好刺激下,中国出境旅游市场持续升温,2016年我国公民出境旅游人数预计达到1.22亿人次,旅游花费1098亿美元. 与之相对应的,是百度.阿里.腾讯三大互联网领军企业旗下的第三方支付平台,正在随着消费升级和境外旅游的热潮,向全球进行跨境支付的版图扩张. 文/张书乐(微信公众号:zsl13973399819) TMT行业观察者.游戏产业时评人,

高级算法——贪心算法(找零问题)

function makeChange(origAmt, coins) {//贪心算法——找零问题 var remainAmt ; if (origAmt % .25 < origAmt) { coins[3] = parseInt(origAmt / .25); remainAmt = origAmt % .25; origAmt = remainAmt; } if (origAmt % .1 < origAmt) { coins[2] = parseInt(origAmt / .1); r

NYOJ995硬币找零(简单dp)

1 /* 2 题意:给你不同面额的硬币(每种硬币无限多),需要找零的面值是T,用这些硬币进行找零, 3 如果T恰好能被找零,输出最少需要的硬币的数目!否则请输出剩下钱数最少的找零方案中的最少硬币数! 4 5 思路:转换成完全背包的问题! 6 */ 7 #include<iostream> 8 #include<cstring> 9 #include<cstdio> 10 #include<algorithm> 11 #define INF 0x3f3f3f3

编程之美之买票找零

题目:假设有2N个人在排队买票,其中有N个人手持50元的钞票,另外有N个人手持100元的钞票,假设开始售票时,售票处没有零钱,问这2N个人有多少种排队方式,不至使售票处出现找不开钱的局面? 分析:队伍的序号标为0,1,...,2n-1,并把50元看作左括号,100元看作右括号,合法序列即括号能完成配对的序列.对于一个合法的序列,第0个一定是左括号,它必然与某个右括号配对,记其位置为k.那么从1到k-1.k+1到2n-1也分别是两个合法序列.那么,k必然是奇数(1到k-1一共有偶数个),设k=2i

硬币找零问题

硬币找零问题一个经典问题,也是阐述动态规划法几乎必讲的一个例子. 硬币找零问题描述:现存在一堆面值为 V1.V2.V3 - 个单位的硬币, 各单位的硬币数目不限, 问最少需要多少个硬币才能找出总值为 T 个单位的零钱? 比如: 假设这一堆面值分别为 1.2.5.21.25 元,需要找出总值 T 为 63 元的零钱. 基于动态规划的思想,我们可以从目标值为 1 元开始计算出最少需要几个硬币,然后再求 2 元.3元- 每一次求得的结果都保存在一个数组中,以后需要用到时则直接取出即可. #includ

11.动态规划(4)——找零问题

找零问题:需找零金额为W,硬币面值有(d1, d2, d3,…,dm),最少需要多少枚硬币. 问题:需找零金额为8,硬币面值有(1, 3, 2, 5),最少需要多少枚硬币. 设F(j)表示总金额为j时最少的零钱数,F(0) = 0,W表示找零金额,有零钱一堆{d1, d2, d3,…,dm}.同样根据之前的经验,要达到为j,那么必然是j – di(1 <= i <= m)面值的硬币数再加1个di面值的硬币,当然j >= di,即F(j) = F(j - di) + 1, j >=

硬币找零问题之动态规划

今天我们看一下动态规划的硬币找零问题,主要通过一系列编程题分析动态规划的规律,只要掌握这一规律,许多动态规划的相关问题都可以类比得到. 题目1:给定数组arr,arr中所有的值都是正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数. 举例: arr[5,2,3],aim=20.  4张5元可以组成20元,其他的找钱方案都要使用更多张的货币,所以返回4. 题解: 一眼看去这道题好像可以用贪心算法可解,但是仔细分析发现有

硬币找零问题的动态规划实现

一,问题描述 给定一组硬币数,找出一组最少的硬币数,来找换零钱N. 比如,可用来找零的硬币为: 1.3.4   待找的钱数为 6.用两个面值为3的硬币找零,最少硬币数为2.而不是 4,1,1 因此,总结下该问题的特征:①硬币可重复多次使用.②在某些情况下,该问题可用贪心算法求解.具体可参考:某种 找换硬币问题的贪心算法的正确性证明 二,动态规划分析 为了更好的分析,先对该问题进行具体的定义:将用来找零的硬币的面值存储在一个数组中.如下: coinsValues[i] 表示第 i 枚硬币的面值.比