1、用动态规划法求解的问题具有的特征
(1)原问题可以分成子问题
(2)子问题之间的递归具有最优子结构的性质
2、动态规划法设计算法一般分成三个阶段
(1)分解
将原问题分解成若干个相互重叠的子问题。
(2)分析
分析问题是否满足最优性原理,找出动态规划函数的递推式
(3)求解
利用递推式自底向上计算,实现动态规划过程
总之,动态规划法利用问题的最优性原理,以自底向上的方式从子问题的最优解逐步构造出整个问题的最优解。
3、应用的问题
(1)0/1背包问题
a、问题的形式化描述如下:
输入:一个物品集S={1,2,...,n}。物品i有重量Wi和价值Vi。重量上限W。
输出:价值总量最大且重量小于W的物品子集。
(注:这里0/1的意思是我们只能选择这个物品,或者放弃这个物品,不能选择物品的部分,如物品的0.5个)
b、分析与解决
我们将求解过程想象成一系列的决策。在第i个决策时,我们考虑是否选择这个物品i
假设我们已经获得最优解,考虑第一个决策,即最优解中有没有物品n(要不要选物品n)
选择:需要从{1,2,...,n-1}中选择尽可能贵的物品使得物品重量在W-wn以下
不选:我们需要从{1,2,...,n-1}中选择尽可能贵的物品使得重量在W以下
则可以分析出最优子结构:
c、0/1背包伪代码
首先,当没有物品时,背包能装最大价值为0;当开始有物品时按照上面写的结构进行依次选择。
KNANSACK(n,W)
for w=1 to W do
opt[0,w]=0
end for
for i=1 to n do
for w=1 to W do
opt[i,w]=max{opt[i-1,w],opt[i-1,w-wi]+vi}
end for
end for
d、表格化看0/1背包
假设背包容量为6,有三个物品分别为
w1=2 | v1=2 |
w2=2 | v2=2 |
w3=3 | v3=3 |
将其用表格来表示每次选择
i\w | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
3 | 0 | 0 | 2 | 3 | 3 | 5 | 5 |
2 | 0 | 0 | 2 | 2 | 4 | 4 | 4 |
1 | 0 | 0 | 2 | 2 | 2 | 2 | 2 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
关于应用还没写完,后面将再补充几个动态的例子及应用的代码~