动态规划

动态规划

动态规划(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
View Code
原文地址:https://www.cnblogs.com/zoulingjin/p/9379613.html