1、以故事的方式来讲述何为动态规划
在看了MIT的算法导论教学视频后。我对动态规划的思想依旧不太清楚。
直至到我看到这么一篇文章,这么一个故事。一个聪明的国王与金矿的故事。
http://www.cnblogs.com/sdjl/articles/1274312.html
看完总结:
引用百度百科对动态规划的定义——
把多阶段过程转化为一系列单阶段问题。利用各阶段之间的关系。逐个求解,创立了解决这类过程优化问题的新方法。
2、区分于分治法
- 共同点:二者都要求原问题具有最优子结构性质,都是将原问题分而治之,分解成若干个规模较小(小到非常easy解决的程序)的子问题.然后将子问题的解合并,形成原问题的解.
- 分治法与动态规划实现方法:
①分治法通常利用递归求解.
②动态规划通常利用迭代法自底向上求解,但也能用具有记忆功能的递归法自顶向下求解.
- 分治法与动态规划主要差别:
①分治法将分解后的子问题看成相互独立的.
②动态规划将分解后的子问题理解为相互间有联系,有重叠部分.
3、动态规划的思考要点
(1)最优子结构——当子问题最优时母问题通过优化选择后一定最优的情况,这个也成为最优化原理。
(2)子问题重叠——之所以用动态规划是由于要把复杂的问题细分,不断地迭代下去。子问题是类似的,可是却不是全然同样。所以说是重叠的。
(3)要确定明显的边界——就像故事里国王依靠大臣。大臣依靠以下的官员等,一层层地不断地依赖子问题得到解决。从而就像多骨诺牌效应一样。
因此。必须保证最后的子问题得到解决,不然。母问题永远解不了。
4、利用动态规划解决最长公共字符串的问题
最后还是把MIT的视频教程看完了,然后里面解说的就是最长公共字符串的问题,因此给出动态规划解决该问题的源代码,供大家參考。
<pre name="code" class="java">
public class CommonSubsequence { public static void main(String[] args) { String[] x = {"A", "B", "C", "B", "D", "A", "B"}; String[] y = { "B", "D", "C", "A", "B", "A"}; int[][] tempArray = calStringLength(x, y); printString(tempArray , x, x.length-1, y.length-1); } public static int[][] calStringLength(String[] x, String[] y) { int[][] temp1 = new int[x.length][y.length]; int[][] temp2 = new int[x.length][y.length]; for(int i=1; i<x.length; i++) { for(int j=1; j<y.length; j++) { if( x[i] == y[j]) { temp2[i][j] = temp2[i-1][j-1] + 1; temp1[i][j] = 1; } else if(temp2[i-1][j] >= temp2[i][j-1]) { temp2[i][j] = temp2[i-1][j]; temp1[i][j] = 0; }else { temp2[i][j] = temp2[i][j-1]; temp1[i][j] = -1; } } } return temp1; } public static void printString(int[][] b, String[] x, int i, int j) { if(i == 0 || j == 0) return; if(b[i][j] == 1) { printString(b, x, i-1, j-1); System.out.print(x[i] + " "); } else if(b[i][j] == 0) { printString(b, x, i-1, j); } else if(b[i][j] == -1) { printString(b, x, i, j-1); } } }