DP初步:状态转移与递推
最少硬币问题
- 有多个不同面值的硬币(任意面值)
- 数量不限
- 输入金额S,输出最少硬币组合。
回顾用贪心求解硬币问题
硬币面值1、2、5。支付13元,要求硬币数量最少
贪心:
(1)5元硬币,2个
(2)2元硬币,1个
(3)1元硬币,1个
硬币面值1、2、4、5、6.,支付9元。
贪心:
(1)6元硬币,1个
(2)2元硬币,1个
(3)1元硬币,1个
错误!
答案是:5元硬币+4元硬币=2个
硬币问题的正解是动态规划
type = [1,5,10,25,50] 5种面值
定义数组Min[],记录最少硬币数量:
对输入的某个金额i,Min[i]是最少的硬币数量
第一步,只考虑1元面值的硬币
金额i: 0,1,2,3,4,5
硬币数量`Min[]`:0,1,2,3,4
- i=1元时,等价于:i = i - 1 = 0 元需要的硬币数量,加上1个1元硬币
- i=2元时,等价于:i = i - 1 = 1 元需要的硬币数量,加上1个1元硬币
- …
在1元硬币的计算结果基础上,再考虑加上5元硬币的情况,从i=5开始就行了
i=5元时,等价于
- i = i - 5 = 0元需要的硬币数量,加上1个5元硬币,
Min[5] = 1 - 原来的
Min[5] = 5
取1和2的最小值,所以Min[5] = 1
i = 6元时,等价于 - i = i - 5 = 1元需要的硬币数量,加上1个5元硬币,
Min[6] = 2 - 原来的
Min[6] = 6
取1和2的最小值,所以Min[6] = 2
Min[6] = Min[5] + 1
递推关系:
Min[i] = min (Min[i], Min[i - 5] + 1)
继续处理其它面值硬币
#include <iostream>
#include <vector>
#include <limits.h>
using namespace std;
void solve(int s)
{
int cnt = 5; //5种硬币
vector<int> type = {1,5,10,25,50}; //5种面值
vector<int> Min(s+1, INT_MAX); //初始化为无穷大
Min[0] = 0;
for (int j = 0; j < cnt; j ++) //5种硬币
{
Min[i] = min (Min[i], Min[i - type[j]] + 1);
}
cout << Min[s] << endl;
}
int main()
{
int s;
cin >> s;
solve(s);
return 0;
}
DP的两个特征
- 重叠子问题
在递归算法中,尤其是在解决最优化问题时,经常会遇到这样的情况:在求解大问题的过程中,我们需要多次求解规模更小、结构相同的问题。这些小问题被称为子问题。如果这些子问题在大问题求解过程中被重复计算多次,这将导致算法效率低下,因为大量时间被重复的子问题求解所占据。动态规划通过存储子问题的解(通常在二维数组中,称为DP表),确保每个子问题只计算一次,从而避免了重复计算。当需要某个子问题的解时,直接从DP表中查找,如果该子问题尚未解决,则先解决它,然后存储其解。 - 最优子结构
这是动态规划能够成功解决许多问题的另一个关键特性。最优子结构是指一个问题的最优解包含其子问题的最优解。换句话说,如果我们能找到所有子问题的最优解,那么我们可以通过这些子问题的最优解来构建原问题的最优解。动态规划利用这个性质,通过自底向上的方式(即先解决最基础的子问题,然后逐步解决更大规模的子问题)来构建问题的最优解。
DP:记忆化
如果各个子问题不是独立的,如果能够保存已经解决的子问题的答案,在需要的时候再找出已求得的答案,可以避免大量的重复计算。
基本思路:用一个表记录所有已解决的子问题的答案,不管该问题以后是否被用到,只要它被计算过,就将其结果填入表中。
记忆化
解题步骤
- 拆分问题
- 定义状态(并找出初状态)
- 状态转移方程
一般的模型方法 - 递归搜索法
- 记忆化搜索(记忆化暴力)
- 递推式法
最经典的DP问题:0/1背包
给定n种物品和一个背包,物品i的重量是wiw_{i}wi其价值为viv_{i}vi,背包的容量为C.
背包问题:选择装入背包的物品,使得装入背包中物品的总价值最大
如果在选择装入背包的物品时,对每种物品i只有两种选择:装入背包或不装入背包,称为0/1耆包问题,
与装载问题不同的是,0/1背包不能只装一部分,要么选,要么不选。
设xix_{i}xi表示物品i装入背包的情况
xix_{i}xi=0,表示物品i没有被装入背包
xix_{i}xi=1,表示物品i被装入背包
约束条件:

本文介绍了动态规划在解决最少硬币问题中的应用,通过状态转移和递推关系展示了如何通过贪心策略优化,以及如何通过记忆化避免重复计算。同时提及了0/1背包问题作为动态规划的经典案例。
最低0.47元/天 解锁文章
2722

被折叠的 条评论
为什么被折叠?



