动态规划算法备忘

 

步骤

1,满足dp算法的必要条件:最优子结构

2,定义递归函数, <-- 这步是关键,

3,自底向上计算递归函数

4,从计算过程保存的信息中,构造最优解的细节

很多实际问题需要从所有可能的情况中找出所需要的情况,有时这没有公式,唯一的办法是搜索、穷举,而随着问题规模扩大,单纯的穷举耗费问题规模的指数时间,对于大规模的问题,即使用计算机解决也很不可取。当问题具有最优子结构时,相同的子问题只需要计算一次,在自底向上的求最优解过程中,仅有子问题就能在可接受的时间复杂度内,计算出更接近最终最优解的子问题,最终完成最优解的计算。动态规划算法的这个特点:对子问题只计算一次,可以看做对穷举算法的一个很有效的剪枝。使得算法时间复杂度有很大很进。dp的自底向上计算过程是对最优子结构的运用:新问题被分解成一系列子问题,这些子问题的最优解都已求出,这时新问题的最优解面临一系列选择,从这一系列选择中构造新问题的最优解,依次类推以新问题为子问题构造更新的问题,直至原问题的最优解。这就是Dynamic Programming。

举例备忘

描述:
在二维坐标上给N个点(N是偶数)的坐标,坐标都是整数,可以任意联接其中两点(不管中间有没有障碍),这两点就消失了(和游戏里的一样).但消去两点的路径和两个点的位置有关,也就是说路径的长度等于两点X轴与Y轴差的绝对值之和.比如一个点坐标为(10,10),另外一个点坐标为(2,3),那么消去这两个点的路径长度为8+7=15.问消去所有点的路径长度之和最小值是多少?

动态规划解法:

输入点对 P1, P2, P3, ... , Pn 。坐标(x, y),点对的和表示为: distance(i,j) = | Pi.x - Pj.x | + | Pi.y - Pj.y | ,求点对序列S:(s1,s2), (s3,s4), ... , (sn-1, sn),使得 distance(s1,s2) + distance(s3,s4) + ... + distance(sn-1,sn)最小, 1 <= s1, s2, ..., sn <= n。

1,最优子结构显而易见,从最优解中任意剔除一对点,得到的点对也是剩余的点的最优解。

2,递归函数:


递归函数S(len, i, j)定义为:从对点长度为len对 ,且所有点对中不包含点Pi,Pj时,可以找到的所有的len对点对序列中最小长度和的点对序列。 1 <= len <= n / 2,1 <= i, j <= n;

E(len, i, j, k),表示某个最优解为S(len, i, j)的子问题中是否含有Pk,用0代表S(len, i, j)包含Pk, 1代表不包含。


那么,已知所有点对长度为len - 1的S(len - 1, i, j)时(对给定长度len,S共有n(n-1)/2种),求一新问题S(len,i,j)的最小值时,假定新问题包括某一点对(k,l),考虑下面两种情况:


1,如果S(len-1,k,l)不包括i和j,那么如果包含点k,l的S(len,i,j)最小值肯定是等于S(len-1,k,l)+d(k,l),因为S(len-1,k,l)的定义就是长度为len-1且不包括(k,l)的子问题最优解。

2,如果S(len-1,k,l)包含了i,j,S(len, i, j)仍然可能包含点k,l,因此这种情况下不应该舍弃点k,l,而应该在长度为len-1的所有(n^2/2-n)个子问题S(len-1,x,y)中选择一个不包含点k,l和点i,j的子问题S(len-1,sub_i,sub_j),由S(len-1,sub_i,sub_j)+d(k,l)构成S(len, i, j)。 

 

从上诉两种情况中,得出S(len,i,j),即:从所有(k,l)点对假设中得到的一系列S(len,i,j)的最小值。

 

综合以上分析,得到递归函数S和E:

 

S(len, i, j) = min {

                             min {

                                     S(len - 1, x, y) : 所有不包含点i, j, k, l的S(len - 1, x, y)

                             }   + d(k, l) : 所有非i, j的点k, l

                    } = S(len - 1, sub_i, sub_j) + d(new_i, new_j)

 

 S式中对点的包含关系用E数组来记录,E数组也递归计算:

 E(len, i, j, k) = E(len - 1, sub_i, sub_j, k)(k为变量), 且 E(len, i, j, new_i) = 0 且 E(len, i, j, new_j) = 0

 

S式和E式就是该问题的一个dp解法的递归函数。

 

直觉上,S数组代表共有n^3/2个子问题,每个子问题由(n^2/2-n)个(k,l)假设计算得到,每个(k,l)假设)要考虑所有len-1的(n^2/2 - n)个子问题S(len-1, x, y),所以t = O(n^7)

 

剩下的3,4步骤已经很容易

复杂度: 时间7次方,空间4次方  !!!!!!!!!!!!!!!

 

实现:

 

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值