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

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

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

给定一些人民币的面额,数量不限,要求找出金额为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];
}


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

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

分享给朋友:

相关文章

【题解】车厢调度

【题解】车厢调度

【题目描述】有一个火车站,铁路如图所示,每辆火车从A驶入,再从B方向驶出,同时它的车厢可以重新组合。假设从A方向驶来的火车有n节(n<=1000)。分别按照顺序编号为1,2,3,...n。假定在...

【题解】均分蛋糕

【题解】均分蛋糕

【题目描述】小明的生日要到了!根据习俗,他需要将一些派分给大家。他有 N 个不同口味、不同大小的派。有 F 个朋友会来参加我的派对,每个人会拿到一块派(必须一个...

【题解】日期排序

【题目描述】有一些日期,日期格式为“MM/DD/YYYY”。编程将其按日期大小排列。【输入描述】无【输出描述】无【样例输入】15/12/1999 10/21/2003 10/22/2003 02...

【题解】飞奔的马

【题目描述】农场里的马,在草场开心地吃着牧草,直到天色晚了,牧马的人会将马依次按号牌大小,依次放入相应的位置。但是这马总是打乱了顺序,于是牧马人都会想办法把这些马都排好:每次从最前面开始,然后与后面的...

字符串移位包含问题

【题目描述】对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串。给定两个字符串 s_1s1 和 s_2s2,要求判定其中一个字符串是...

【题解】2001-T1 数的计数

【题目描述】我们要求找出具有下列性质数的个数(包含输入的自然数nn):先输入一个自然数n(n≤1000)n(n≤1000),然后对此自然数按照如下方法进行处理:1.不作任何处理;2.在它的左边加上一个...