关闭

硬币面值组合(上台阶)

788人阅读 评论(1) 收藏 举报
分类:

 假设我们有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





0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:415460次
    • 积分:8253
    • 等级:
    • 排名:第2544名
    • 原创:390篇
    • 转载:276篇
    • 译文:0篇
    • 评论:30条
    联系方式
    E-mail:gwh_mail@qq.com QQ:1440156051
    最新评论