高频算法面试题学习总结----动态规划3:换硬币

题目:硬币很多种,价值各不同。拼成一个数。最少用几个?
输入:coins = {1, 2, 3, 4} target = 10
输出:3
解释:最少使用的硬币数是3:包含两个4和一个2

思路分析:

1.贪心法:从最大硬币值开始,逐步往低试。

反例:coins = {1,5,11}    target = 20;    应输出:4(4*5);贪心法输出:6(11+5+4*1)。贪心法pass。

2.动态规划:

解空间树:

图1

代码实现:

#include<iostream>
#include<vector>

using namespace std;

//备忘模型
int GetMemo(vector<int>& coins,vector<int>& memo, int target)
{
	if (memo[target] == -2) {
		int result = -1;
		for (int coin : coins) {
			if (coin <= target) {
				int temp = GetMemo(coins, memo, target - coin);
				if (temp != -1 && (result == -1 || temp + 1 < result))
					result = temp + 1;
			}
		}
		memo[target] = result;
	}
	return memo[target];
}
int GetCoins(vector<int>& coins,int target)
{
	vector<int> memo(target + 1, -2);	//-2表示未计算,-1表示无解
	memo[0] = 0;
	return GetMemo(coins,memo, target);
}

//演绎模型
int GetCoins1(vector<int>& coins, int target)
{
	vector<int> memo(target + 1);
	memo[0] = 0;

	for (int i = 1; i < memo.size(); ++i) {
		int result = -1;
		for (int coin : coins) {
			if (coin <= i) {
				int temp = memo[i - coin];
				if (temp != -1 && (result == -1 || result > temp + 1))
					result = temp + 1;
			}
		}
		memo[i] = result;
	}
	return memo[target];
}

int main()
{
	vector<int> coins({ 1,2,3,4 });
	vector<int> coins1({ 1,5,11 });
	cout << GetCoins(coins1, 20) << endl;
	cout << GetCoins1(coins1, 20) << endl;
	return 0;
}

 

箴言录:

君子欲讷于言而敏于行。 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章