码迷,mamicode.com
首页 > 其他好文 > 详细

找零问题

时间:2014-08-18 23:40:43      阅读:557      评论:0      收藏:0      [点我收藏+]

标签:算法

问题描述:

为找零问题 设计一种动态规划算法:给定金额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;
}

bubuko.com,布布扣

分析输出矩阵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

找零问题

标签:算法

原文地址:http://blog.csdn.net/hishentan/article/details/38666021

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!