动态规划
动态规划是一种算法设计艺术。通常用来解决交叠的子问题构成的大问题。一般来说子问题都符合一定的递推关系,动态规划是将这些子问题的解存下来,这样从记录表中就可以得到原始解。
首先我们来看一个简单的例子:
1.币值最大化问题
给定一排n个硬币,其面值均为正整数 c1,c2,c3,···cn,这些整数
不一定两两不同。如何选择硬币使得在其原始位置互不相邻的条件下所选硬币金额最大。
分两种情况讨论:
设 F(n)为最大可选金额。
包括最后一枚硬币
可选最大值为 cn+F(n-2);
不包括最后一枚硬币
可选最大值为F(n-1)
这样我们可以得到一个状态转移方程: F(i)=max{ci+F(i-2),F(i-1)}
2.最少硬币问题
需要找零的金额为n,需要使用多少个面值不同的硬币/纸币使得用的数量最少。
解题思路:
首先想到一个问题就是当找的零钱数为 n-dj时直接加入dj就可以了,那么我们可以得到下面的转移方程。
首先确定转移方程 :
F(n)=min{F(n-dj)}+1//这里就保证了每次都加入能加入的最大钱币。
接下来递归就好了,只要注意到 F(0)=0就可以了。
经典背包问题
背包问题作为动规解决频率最高的问题,常见的有:
0-1 背包
完全背包
动规问题最核心的解决关键是找出状态转移方程。
背包问题的状态转移方程为
F(i,j)=max{F(i-1,j),vi+F(i-1,j-wi)}
题解:
- 就是要从后往前考虑,F(i-1,j)指的是在不包含i号物品时最优的情况。
F(i-1,j-wi)+vi指的是选这个物品之后能够达到的最优情况。