当前位置:首页 > 题解目录 > 正文内容

【题解】找零钱—动态规划

亿万年的星光4年前 (2021-10-10)题解目录8574

给定一些人民币的面额,数量不限,要求找出金额为m元且人民币张数最少的方案。这个问题既可以是一个贪心问题也可以是一个动态规划的问题。

对于现行的人民币面额:1、2、5、10、20、50、100,我们找任何金额的零钱都可以使用贪心法求解,比如找72元 = 50 + 20 + 2,3张人民币即可实现。

但如果面额发生变化的话,则用贪心算法无法求出最优解,例如面额为1、3、6、7, 要找12元的话只能是 12 = 7 + 3 + 1 + 1必须使用4张人民币,而最优解为12 = 6 + 6,两张人民币即可。因此这种问题一般使用动态规划求解。

侧面说明一点,贪心法大家都会,动态规划就不一定了!

1、动态规划解题思路

设给定的面额为x1,x2,x3。现要求找n元零钱,假设已经找好也就是你已经拿到一叠零钱,它的张数最少且总和恰好为n nn

假设f(n)表示找n nn元钱的最少人民币张数,我们现在关注的是找的这些零钱的最后一张,它只能是

x1,x2...中的任意一张,假设最后一张为xi,那么要使总的人民币张数最少,必然要使子问题f(n-xi)最少。因此,

该状态转移方程为f(n)=min( f(n-xi) + 1)

DP:

int m[5] = {0, 1, 3, 4, 7 };
int dp(int n)
{
	if (n == 1 || n == 3 || n == 4 || n == 7)  return  1; //递归出口
	int ans = INT_MAX;  //因为求最小值,所以这里初始为最大值
	for (int i = 1; i <= 4; i++)
		if (m[i] <= n) ans = min(ans, dp(n - m[i]) + 1);
	return ans;
}

记忆化搜索DP代码如下:

int dp(int n)
{
	if (n == 1 || n == 3 || n == 4 || n == 7)  return ans[n] = 1;
	if (ans[n]) return ans[n];
	ans[n] = INT_MAX;
	for (int i = 1; i <= 4; i++)
		if (m[i] <= n) ans[n] = min(ans[n], dp(n - m[i]) + 1);
	return ans[n];
}


扫描二维码推送至手机访问。

版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

分享给朋友:

相关文章

【题解】背包问题3

【题目描述】完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的体积是c,价值是w。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。本题要求是背...

【题解】切比雪夫距离

【题目描述】小C有一个平面!它发现了平面上的两个点,请你求出求它们之间的切比雪夫距离。切比雪夫距离定义为x与y方向坐标差的绝对值较大值。【输入描述】四个整数,a,b,c,d。坐标为(a,b)与(c,d...

【题解】宴会

【题目描述】今人不见古时月,今月曾经照古人。梦回长安,大唐风华,十里长安花,一日看尽。 唐长安城是当时世界上规模最大、建筑最宏伟、规划布局最为规范化的一座都城。其营建 制度规划布局的特点是规...

猴子吃桃

【题目描述】猴子吃桃问题。猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。 第二天早上又将剩下的桃子吃掉一半,又多吃一个。以后每天早上都吃了前一天剩下的一半零一个。到第N天早上想再吃时...

【题解】BFS、DFS——走迷宫问题

【题目描述】给定一个 n×m的二维整数数组,用来表示一个迷宫,数组中只包含 0 或 1,其中 0 表示可以走的路,1 表示不可通过的墙壁。最初,有一个人位于左上角 (1,...

【题解】滑翔翼

【题目描述】小T和小K都是OIER,入选省队后有幸去苏州参加JSOI集训,训练之余,他们相约一起去苏州乐园玩。苏州乐园里有一个非常热门的游乐项目叫双人滑翔翼。小T想和小K一起乘双人滑翔翼,但是排在他们...