动态规划
动态规划(Dynamic Programming, DP)思想启发于分治算法的思想,也是将复杂问题化解若干子问题,先求解小问题,再根据小问题的解得到原问题的解。但是DP与分治算法不同的是,DP分解的若干子问题,往往是互相不独立的.
DP正是利用一个表记录所有已经求解过的子问题的答案,只要一个子问题被求解过,就将其答案保存起来,无论以后的计算是否会用到,这就是DP的基本思想。
步骤:1.最优子结构 2.重叠子问题 3.自底向上计算最优值 4.构造最优解
下面是几个经典例题
1.最长公共子序列
import java.util.Scanner; //abcdefgh bdfgklm //abcd ac public class Lcs { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入两个字符串: "); String str1 = sc.next(); String str2 = sc.next(); int [][]b = new int[100][100]; int num=lcsLength(str1.toCharArray(),str2.toCharArray(),b); System.out.println("最长公共子序列的长度为: "+num); System.out.print("最长公共子序列是: "); lcsMethod(str1.length(), str2.length(),str1.toCharArray(), b); System.out.println(); } public static int lcsLength(char[]x,char[]y,int [][]b){ int m = x.length; int n = y.length; int i,j; int c[][] = new int[m+1][n+1]; for(i=1;i<=m;i++) c[i][0] = 0; for(i=1;i<=n;i++) c[0][i] = 0; for(i=1;i<=m;i++){ for(j=1;j<=n;j++){ if(x[i-1]==y[j-1]){ c[i][j] = c[i-1][j-1]+1; b[i][j] = 1; }else if(c[i-1][j]>=c[i][j-1]){ c[i][j] = c[i-1][j]; b[i][j] = 2; }else{ c[i][j] = c[i][j-1]; b[i][j] = 3; } } } // System.out.println("友情提示:(1)j→,i↓(2)b为2向上"); System.out.println("c[]数组:"); for(i=0;i<m+1;i++){ for(j=0;j<n+1;j++){ System.out.print(c[i][j]+" "); } System.out.println(); } System.out.println("b[]数组"); for(i=0;i<m+1;i++){ for(j=0;j<n+1;j++){ System.out.print(b[i][j]+" "); } System.out.println(); } return c[m][n]; } public static void lcsMethod(int i,int j,char x[],int b[][]){ if(i==0||j==0) return; if(b[i][j]==1){ lcsMethod(i-1,j-1,x,b); System.out.print(x[i-1]); }else if(b[i][j] == 2){ lcsMethod(i-1,j,x,b); }else{ lcsMethod(i,j-1,x,b); } } }
请输入两个字符串: abcdefgh bdfgklm 友情提示:(1)j→,i↓(2)b为2向上 c[]数组: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 2 2 2 2 2 2 0 1 2 2 2 2 2 2 0 1 2 3 3 3 3 3 0 1 2 3 4 4 4 4 0 1 2 3 4 4 4 4 b[]数组 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 0 1 3 3 3 3 3 3 0 2 2 2 2 2 2 2 0 2 1 3 3 3 3 3 0 2 2 2 2 2 2 2 0 2 2 1 3 3 3 3 0 2 2 2 1 3 3 3 0 2 2 2 2 2 2 2 最长公共子序列的长度为: 4 最长公共子序列是: bdfg