动态规划专项

333 阅读1分钟

最大子序和

题目

image.png

版本1 正确

    public int maxSubArray(int[] nums) {

        // 利用动态规划
        // dp[i] 表示以i结尾的子数组的最大和
        int [] dp = new int[nums.length];

        // base case
        dp[0] = nums[0];

        // 状态转移
        int max = dp[0];
        for (int i = 1; i < dp.length; i ++) {
            dp[i] = Math.max(0, dp[i - 1]) + nums[i];
            max = Math.max(max, dp[i]);
        }

        return max;

    }

正确的原因

(1) 一定要注意 不是dp[nums.length - 1]是最大值, 而是在计算过程中 随时更新最大值

(2) 最大值初始化的时候, 一定要初始化成dp[0], 即int max = dp[0];

爬楼梯

题目

image.png

版本1 正确

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

        // 爬楼梯 每次爬1到2阶
        // 典型的回溯问题 可以用动态规划来解决, 节省大量不必要的回溯

        // dp[i] 表示跳到第i+1个台阶 有多少种方案
        int [] dp = new int[n];

        // base case
        dp[0] = 1;
        dp[1] = 2;

        // 状态转移
        for (int i = 2; i < n; i ++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }

        return dp[n - 1];

    }

正确的原因

(1) 每个台阶只能由一步或者两步跳到. 因此可以用动规