[2016/7/20][algorithm] Dynamic Programming By CSBreakdown

https://www.youtube.com/watch?v=_zE5z-KZGRw&list=PLyEvk8ZeQDMVbsg7CEfT0NV3s3GkMx1vN&index=2

把自己觉得有用的东西整理一下.

1.有最优子结构(optimal substructure)时:

第一步,找到最初的状态很关键。

2.没有最优子结构时

①最长路问题


如图,找A到C的最长路,如果有最优子结构,则是从A到D的最长路加D到C的最长路。

但是,A到D的最长路是A>B>C>D;D到C则是D>C,这样就重复了,违反了不能重复走边的原则。

所以这种情况,独立解拼在一起不能构成最优子结构。

②最大团问题:在一个无向图中找出一个点数最多的完全图。不能把团拆开。

3.矩阵乘法


变换到最后4*3的矩阵,总共需要4*6*3 = 72次加法。


如果多个矩阵相乘的话,总的计算次数1700+。如果数字很大,更慢。

所以要给矩阵们括上括号,减少计算次数。

这时就要用动态规划,找出递推方程。



其中的k是指从哪分割。

过程如下:

先把相邻两矩阵之间相乘的状态找出来。


再利用之前算过的,找三个矩阵相乘的:



以此类推,对于每种状态,枚举不同k值下的结果,并找出最小值补充表格。

最后的表格如下:


至于怎么加括号,可以用逆推法。在上述过程中填表的同时,记录下使其值最小的k值。

加括号步骤如下:


找出最优子结构,并根据最优子结构的k值增加括号。

4.Edit distance

字符串相似程度。


问题:如何把一个字符串变为另一个字符串?所花费的最优步骤是什么?

首先,如果要变,需要以下四步:


所以,步骤如下:

one:初始状态是指把0>knitting和kitten>0。存储花费步骤数和操作。

至于为什么是三个方向,把c看做状态,想一想就知道了。


最后回溯。从最后一个格子,根据存储的操作可以找到上一个格子的内容。一直如此就好。


5.最长子序列,最长递增序列。

最长子序列:

行列坐标分别是两个串。*一栏是初始状态,即其中有一个为0时的状态。

通过状态转移方程,如果两个字母一样,就回溯斜方向的状态。如果两个字母不一样,就选取上,左相邻格子里的最大值。


如果要找具体的序列是什么,就回溯。

如图,上方比左方优先,斜方比上方优先,把操作是斜上的格子的字母记下来,走完就好啦!

但是,可以看出里面的最长公共子序列除yxz之外,还有wxy。这个时候,如果回溯,遇到向上箭头且其上,左的值相同,就分两个方向搜。就可以得出其他的LCS。


6.rob cutting

有一个长度为n的杆,已知不同长度的杆价钱不同,问怎样分才能使整根杆的价值最高。

用记忆化的方式dp。

递推方程是怎么得出来的:首先一个整块问题,Cij,取k>=i且<j,此时k是最优分割方案。于是吧问题转换成Cik,Ckj两块,之后以此类推。至于如何确定k的值,根据递推方程,一个个算,找出价值最大时的k值即可。复杂度是o(N^2).

当补充每个状态的最优解时,应存k,以便到最后找到究竟切哪里。


6.0-1 Knapsack Problem

递推方程如下:因为对于一件物品只能选或不选,且物品不能分割。所以当w<M时,直接比较加上或不加的大小就行了。


按方程的步骤走之后,得到表。

如果要打印挑选的物品,应该这样做。

先在最后一个格子,往上搜,如果数字不一样,则是选了最后一个物品,一样则反之,就一直往上搜。

搜到上一格之后,减去上一件物品的重量,然后再往上搜,以此类推。


7.change making

how can a given amount of money be made with the least number of coins of given denominations? It is a knapsack type problem, and has applications wider than just currency.

递推方程如下:


过程如下:

最后回溯,求找了哪几个硬币:


算法复杂度:O(n*k)

8.Maximum Contiguous Subsequence

求出里面和最大的一串子串。

递推方程及步骤如下。

每起始一个子串,标记起始点。

最后找那个最大和子串,从数组里值最大的那个数字开始回溯,直到遇到第一个标记过的起始点。记录路径上经过的点即可。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值