1、以故事的方式来讲述何为动态规划
在看了MIT的算法导论教学视频后,我对动态规划的思想依然不太清楚。直至到我看到这么一篇文章,这么一个故事。一个聪明的国王与金矿的故事。
http://www.cnblogs.com/sdjl/articles/1274312.html
看完总结:
引用百度百科对动态规划的定义——
把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法。
2、区分于分治法
- 共同点:二者都要求原问题具有最优子结构性质,都是将原问题分而治之,分解成若干个规模较小(小到很容易解决的程序)的子问题.然后将子问题的解合并,形成原问题的解.
- 分治法与动态规划实现方法:
①分治法通常利用递归求解.
②动态规划通常利用迭代法自底向上求解,但也能用具有记忆功能的递归法自顶向下求解.
- 分治法与动态规划主要区别:
①分治法将分解后的子问题看成相互独立的.
②动态规划将分解后的子问题理解为相互间有联系,有重叠部分.
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);
}
}
}