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

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

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

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

C++
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代码如下:

C++
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];
}

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

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

相关文章

【题解】阶乘问题

2.阶乘问题(fac.cpp)【题目描述】给定一个正整数n,求出一个最小的整数m并使得m!的末尾连续的0的个数小于n。m!=1*2*3*4*...*m【输入描述】第一行n。【输出描述】一个整数m。【样...

【题解】游览动物园

【题目描述】动物园有很多游览区,小红已经在动物园的一个游览区游览,突然接到电话,要半个小时内到动物园外面跟一个朋友见面。半个小时小红只够游览完当前区域之后,游览一个最近的景区。已知从一个游览区域只能沿...

【题解】连通块

【题目描述】一个n × m的方格图,一些格子被涂成了黑色,在方格图中被标为1,白色格子标为0。问有多少个四连通的黑色格子连通块。四连通的黑色格子连通块指的是一片由黑色格子组成的区域,其中的每个黑色格子...

【题解】核电站问题

【题目描述】一个核电站有N个放核物质的坑,坑排列在一条直线上。如果连续3个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质。现在,请你计算:对于给定的N,求不发生爆炸的放置核物质的方案总数...

【题解】老王赛马

【题目描述】赛马是一古老的游戏,早在公元前四世纪的中国,处在诸侯割据的状态,历史上称为“战国时期”。在魏国作官的孙膑,因为受到同僚庞涓的迫害,被齐国使臣救出后,到达齐国国都。 赛马是当时最受...

【题解】种花问题

【题目描述】假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。给你一个整数数组 flowerbed 表示花坛,...