硬币面值组合(上台阶)

原创 2016年05月30日 11:24:56

 假设我们有8种不同面值的硬币{1,2,5,10,20,50,100,200},用这些硬币组合够成一个给定的数值n。问总过有多少种可能的组合方式? 类似的题目还有:

  [华为面试题] 1分2分5分的硬币三种,组合成1角,共有多少种组合

  [创新工厂笔试题] 有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱,有多少中组合可以组成n分钱

  • 一个人上台阶可以一次上1个,2个,或者3个,问这个人上n层的台阶,总共有几种走法? 
    问法不一样,但是本质一样!


1.方法一

深度搜索解答树

#include<iostream>
#include<vector>
using namespace std;

int coin[4] = { 1, 2, 5, 10 };
vector<int> solution;
int cnt = 0;
int sum = 0;

int target = 0;

void dfs(int index){
	if (sum == target){
		cnt++;

		for (int i = 0; i<solution.size(); i++){
			cout << solution[i];
		}
		cout << endl;
		return;
	}
	if (sum > target){
		return;
	}

	for (int i = index; i < 4; i++){// index,否则有重复
		sum += coin[i];
		solution.push_back(coin[i]);
		dfs(i);
		solution.pop_back();
		sum -= coin[i];
	}

}

int main(){

	cnt = 0;
	sum = 0;

	target = 5;

	dfs(0);

	cout << "cnt=" << cnt << endl;

	return 0;
}
结果为4

2.方法二-动态规划

给定一个数值sum,假设我们有m种不同类型的硬币{V1, V2, ..., Vm},如果要组合成sum,那么我们有

sum = x1 * V1 + x2 * V2 + ... + xm * Vm 

求所有可能的组合数,就是求满足前面等值的系数{x1, x2, ..., xm}的所有可能个数。

dp[i][sum] = 用前i种硬币构成sum 的所有组合数。

  那么题目的问题实际上就是求dp[m][sum],即用前m种硬币(所有硬币)构成sum的所有组合数。

dp[i][sum] = dp[i-1][sum - 0*Vm] + dp[i-1][sum - 1*Vm]

+ dp[i-1][sum - 2*Vm] + ... + dp[i-1][sum - K*Vm]; 其中K = sum / Vm

那么初始情况是什么呢?如果sum=0,那么无论有前多少种来组合0,只有一种可能,就是各个系数都等于0;

dp[i][0] = 1   // i = 0, 1, 2, ... , m

我们规定为dp[0][sum] = 0. 

#include<iostream>
#include<vector>
using namespace std;


int coinCombination(int coin[], int coinKinds, int target){
	vector<vector<int> >dp(coinKinds + 1, vector<int>(target + 1));

	for (int i = 0; i <= coinKinds; i++){
		dp[i][0] = 1;
	}

	dp[0][target] = 0;

	for (int i = 1; i <= coinKinds; i++){
		for (int j = 1; j <= target; j++){
			dp[i][j] = 0;
			for (int k = 0; k <= j / coin[i - 1]; k++){//<=
				dp[i][j] += dp[i - 1][j - k*coin[i - 1]];//+=
			}
		}
	}

	return dp[coinKinds][target];
}


int main(){

	int coin[4] = { 1, 2, 5, 10 };

	cout << coinCombination(coin, 4, 5) << endl;

	return 0;
}

http://www.cnblogs.com/python27/p/3303721.html





版权声明:本文为博主原创文章,未经博主允许不得转载。

动态规划-金额为Sum的所有纸(硬)币组合

问题 给定一个数值sum,假设我们有m种不同类型的硬币{V1, V2, ..., Vm},如果要组合成sum,求所有可能的组合数。 经典面试题 [华为面试题]  ...

硬币的面值组合个数

http://www.cnblogs.com/python27/archive/2013/09/05/3303721.html 假设我们有8种不同面值的硬币{1,2,5,10,20,50,1...

硬币面值组合的算法题解

方法一 转自http://www.cnblogs.com/python27/archive/2013/09/05/3303721.html 动态规划的方法,是将m*n(m表示硬币的种类,n表示所要组...

硬币组合算法

问题: 有足够多的面值25分、10分、5分和1分的硬币, 用它们来组合出 n 分钱 解决方案:用递归的思想,a b c d代表各币种硬币的数量,字典dict用来存储已经试探过的组合,列表x用来存储所...

程序员面试金典(动态规划):1分,5分,10分,25分硬币面值组合问题(解题思路)

问题描述: 假设我们有8种不同面值的硬币{1,2,5,10,20,50,100,200},用这些硬币组合够成一个给定的数值n。例如n=200,那么一种可能的组合方式为 200 = 3 * 1...

动态规划之硬币面值组合问题

原文链接:http://www.cnblogs.com/python27/archive/2013/09/05/3303721.html问题描述   假设我们有8种不同面值的硬币{1,2,5,10,...

硬币选择问题-动态规划

最少硬币问题 假设有3种不同的硬币,币值分别是CoinValue[] = {1, 2, 5},每一种硬币的数量是有限的,分别是CoinNum[] = {3, 3, 3},给定一个数值target=1...

动态规划之硬币组合问题

问题:如果我们有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?   动态规划的本质是将原问题分解为同性质的若干相同子结构,在求解最优值的过程中将子结构的最优值记录到一个表中以避免...

硬币组合问题-动态规划

如果我们有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元? (表面上这道题可以用贪心算法,但贪心算法无法保证可以求出解,比如1元换成2元的时候) 首先我们思考一个问题,如何用最少...

【动态规划】硬币面值组合(上台阶)

问题 1分2分5分的硬币三种,组合成1角,共有多少种组合? 有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱,有多少中组合可以组成n分钱? 一个人上台阶可以一次上1个,2个,或者3...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:硬币面值组合(上台阶)
举报原因:
原因补充:

(最多只允许输入30个字)