0
点赞
收藏
分享

微信扫一扫

【动态规划】 习题总结

胡桑_b06e 2022-02-20 阅读 78

1.整数拆分

递归公式

代码

// 题目描述:将正整数n无序拆分成最大数为k的拆分情况。拆分方案不重复
    public static int split(int n,int k){
        int [][] dp = new int[n+1][k+1];
        dp[0][0] = 0;
        int i, j;
        for (i = 1; i <= n; i++){
            for (j = 1; j <= k; j++){
//                n = 1 ,k = 1时候 dp[i][j] = 1
                if (i == 1 || j == 1){
                    dp[i][j] = 1;
                }else if(i < j){
                    dp[i][j] = dp[i][i];
                }else if (i == j){
                    dp[i][j] = dp[i][j-1] + 1;
                }else if(i > j){
                    dp[i][j] = dp[i-j][j] + dp[i][j-1];
                }
            }
        }
        return dp[n][k];


    }

2.最长公共子序列

递归公式

代码

//    求最长公共子序列的长度
    public static int commonLen(String s1,String s2){
        int len1 = s1.length();
        int len2 = s2.length();
//        进行空与字符串比较 【特殊情况】
        for (int i = 0; i <= len1; i++){
            dp[i][0] = 0;
        }
        for (int i = 0; i <= len2;i++){
            dp[0][i] = 0;
        }
        for (int i = 1; i <= len1; i++){
            for (int j = 1; j <= len2;j++){
//                 如果两者相等,则选择左上角+1
                if (s1.charAt(i-1) == s2.charAt(j-1)){
                    dp[i][j] = dp[i-1][j-1]+1;
                }else{
//                   不相等,选择当前数上边和左边较大的数
                    dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }
        return dp[len1][len2];
    }

3.0/1背包

递推公式

代码

    public static int knep(int f[][],int w[],int val[],int W,int n){
//        边界初始化操作:当W=0时候
        for (int i = 0; i <= n;i++)
            f[i][0] = 0;
//        边界初始化操作:当w[i] = 0的时候。
        for (int r = 0; r <= W;r++)
            f[0][r] = 0;
//        遍历操作
        for (int i = 1; i <= n;i++){
            for (int r=1; r <= W;r++){
//                装不下时候,不装。
                if (r < w[i]){
                    f[i][r] = f[i-1][r];
                }else{
//                    装得下,比较是否要装入。
                    f[i][r] = Math.max(f[i-1][r],f[i-1][r-w[i]]+val[i]);
                }
            }
        }
        return f[n][W];
    }

4.完全背包

递归公式:

代码

    public static int solve(int w[],int f[][],int val[],int W,int n){
        for (int i = 1; i <= n;i++){
            for (int j = 1; j <= W;j++){
//                放不下
                if (j - w[i-1] < 0){
                    f[i][j] = f[i-1][j];
                }else{ // 放的下
//                   放:几次
                    if (f[i-1][j] < f[i][j -w[i-1]] +val[i-1]){
//                        注意这里是f[i][j-w[i]] 表示当前的物品能够放几次。
                        f[i][j] = f[i][j-w[i-1]] +val[i-1];
                    }else{
//                        不放
                        f[i][j] = f[i-1][j];
                    }
                }
            }
        }
        return f[n][W];
    }

5.最大连续子序列和

递推公式

代码

    public static int[] lcs(int[]a){
        int n = a.length;
        int b[] = new int[n+1];
        b[0] = a[0];
        int j =1;
      for (int i=1; i < n;i++){
          b[j] = Math.max(b[j-1]+a[i],a[i]);
          j++;
      }
        return b;
    }


6.单调递增子序列

递推公式

代码

    public static int lis(int [] a){
        int len = a.length;
        int b[] = new int[len];
        b[0] = 1;
        for (int i =1; i < len;i++){
            int k = 0;
            for (int j = 0; j < i; j++){
//                递增且获取之前存储过最大的连续递增长度
                if (a[j] <= a[i] && k < b[j]){
                    k = b[j];
                }
            }
            b[i] = k+1;
        }
        return b[len-1];
    }
举报

相关推荐

0 条评论