据我所知,DP要么是你从更大的问题开始并递归下来,并且每次都要保存这些值以备将来使用,要么你会反复进行并保持价值自下而上。但是,如果我自下而上,但递归上升呢?
比如说以下问题,Longest Common Subsequence
这是我的解决方案
public class LongestCommonSubseq {
/**
* @param args
*/
public static List<Character> list = new ArrayList<Character>();
public static int[][] M = new int[7][7];
public static void main(String[] args) {
String s1 = "ABCDGH";
String s2 = "AEDFHR";
for(int i=0;i<=6;i++)
for(int j=0;j<=6;j++)
M[i][j] = -1;
int max = getMax(s1,s2,0,0);
System.out.println(max);
Collections.sort(list);
for(int i = 0;i < max;i++)
System.out.println(list.get(i));
}
public static int getMax(String s1, String s2,int i ,int j){
if(i >= s1.length() || j>= s2.length()){
M[i][j] = 0;
return M[i][j];
}
if(M[i][j] != -1)
return M[i][j];
if(s1.charAt(i) == s2.charAt(j)){
M[i][j] = 1 + getMax(s1,s2,i+1,j+1);
list.add(s1.charAt(i));
}
else
M[i][j] = max(getMax(s1,s2,i+1,j) , getMax(s1, s2, i, j+1));
return M[i][j];
}
public static int max(int a,int b){
return a > b ? a : b;
}
}
所以你看,我在另一个方向从M [0] [0]开始,但我不是在迭代地做。 但我想它应该没问题。只需要确认。
由于
答案 0 :(得分:1)
方向无关紧要。更重要的是,你从更一般的(复杂的)问题转向更简单的问题。你所做的是动态编程。
答案 1 :(得分:1)
对于动态编程,如果您遵循自下而上或自上而下范例,则无关紧要。动态规划的基础论文(如你已经正确提到的)被称为 Bellman的最优性原理,其中包括:
最优性原则:最优政策具有以下特性 无论初始状态和初始决定是什么,剩下的 决策必须构成关于国家的最佳政策 由第一个决定产生。
资源:维基百科(http://en.wikipedia.org/wiki/Bellman_equation#Bellman.27s_Principle_of_Optimality)
从递归调用树中删除一些这些最佳子解决方案的好方法是使用缓存(就像在代码中一样)。