动态规划

Posted 保护眼睛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划相关的知识,希望对你有一定的参考价值。

动态规划的基本的特点就是:
1.把原来的问题划分成相似的子问题
2.所有的子问题只需要解决一次
3.存储子问题的解
本质上就是状态的定义、和状态的转移方程的定义。
还有就是状态的初始化、还有返回结果
状态之间一定要有递推的关系。
动态规划解决的问题:
最值的问题、方法的个数、可不可行的问题、方案的个数的问题

70.爬楼梯

class Solution {
    public int climbStairs(int n) {
        if (n == 1){
            return 1;
        }

        int[] dp = new int[n+1];
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n ;i++){
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
    }
}
    public static int climbStairs1(int n){
        if (n == 1){
            return 1;
        }
        int f1 = 1;
        int f2 = 2;
        int sum = 0;
        for (int i = 3; i <= n ; i++) {
            sum = f1 + f2;
            f1 = f2;
            f2 = sum;
        }
        return sum;
    }

53.最大字序和

    public static int maxSubArray(int[] nums) {
        int preArr = nums[0];
        int res = nums[0];
        for (int i = 1; i < nums.length; i++) {
            preArr = Math.max(nums[i],preArr+nums[i]);
            res = Math.max(res,preArr);
        }
        return res;
    }

300.最长递增子序列

    public static int lengthOfLIS(int[] nums) {
        if (nums.length == 0 || nums == null)
            return 0;
        int res = 1;
        int len = nums.length;
        int[] tmpArr = new int[len];
        for (int i = 0; i < len; i++) {
            tmpArr[i] = 1;
        }

        for (int i = 1; i < len; i++) {
            for (int j = i - 1; j >= 0; j--) {
                if (nums[i] > nums[j]) {
                    tmpArr[i] = Math.max(tmpArr[i], tmpArr[j] + 1);
                } else {
                    continue;
                }
            }
        }
        for (int i = 0; i < len; i++) {
            res = Math.max(res, tmpArr[i]);
        }
        return res;
    }

120.三角形的最小的路径和

    public int minimumTotal(List<List<Integer>> triangle) {
        int n = triangle.size();
        int[][] dp = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < i + 1; j++) {
                Integer num = triangle.get(i).get(j);
                if (i == 0) dp[i][j] = num;
                else if (j == 0) dp[i][j] = dp[i - 1][j] + num;
                else if (i == j) dp[i][j] = dp[i - 1][j - 1] + num;
                else {
                    dp[i][j] = Math.min(dp[i - 1][j - 1] + num, dp[i - 1][j] + num);
                }
            }
        }
        int minRes = dp[n - 1][0];
        for (int i = 0; i < dp[n - 1].length; i++) {
            minRes = Math.min(minRes, dp[n - 1][i]);
        }
        return minRes;
    }

64.最小路径和

    public static int minPathSum(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;

        int[][] res = new int[m][n];
        res[0][0] = grid[0][0];

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (i == 0 && j != 0) {
                    res[i][j] = res[i][j - 1] + grid[i][j];
                } else if (j == 0 && i != 0) {
                    res[i][j] = res[i - 1][j] + grid[i][j];
                } else if (j != 0 && i != 0) {
                    res[i][j] = Math.min(grid[i][j] + res[i - 1][j], res[i][j - 1] + grid[i][j]);
                }
            }
        }
        return res[m - 1][n - 1];
    }

198.打家劫舍

    public static int rob(int[] nums) {
        if (nums == null)
            return 0;
        if (nums.length == 1)
            return nums[0];

        int len = nums.length;
        int[] tmpArr = new int[len];
        tmpArr[0] = nums[0];
        tmpArr[1] = Math.max(nums[1],nums[0]);

        for (int i = 2; i < len; i++) {
            tmpArr[i] = Math.max(tmpArr[i - 2] + nums[i], tmpArr[i - 1]);
        }
        return tmpArr[len-1];
    }
    public static int rob1(int[] nums) {
        if (nums == null)
            return 0;
        if (nums.length == 1)
            return nums[0];

        int len = nums.length;
        int tmp1 = nums[0];
        int tmp2 = Math.max(nums[1],nums[0]);

        for (int i = 2; i < len; i++) {
            int tmp = tmp2;
            tmp2 = Math.max(tmp1+nums[i],tmp2);
            tmp1 = tmp;
        }
        return tmp2;
    }

以上是关于动态规划的主要内容,如果未能解决你的问题,请参考以下文章

是否可以动态编译和执行 C# 代码片段?

动态规划_线性动态规划,区间动态规划

应对笔试手写代码,如何准备动态规划?

应对笔试手写代码,如何准备动态规划?

应对笔试手写代码,如何准备动态规划?

算法动态规划 ⑤ ( LeetCode 63.不同路径 II | 问题分析 | 动态规划算法设计 | 代码示例 )