Skip to content

Latest commit

 

History

History
 
 

README.md

学习笔记 第六周

2021.3.9

每日一题

零钱兑换

第5周 第12课 | 动态规划(二)

1.实战题目解析:三角形最小路径和

DP:

  1. 找到重复性
  2. 定义状态数组
  3. DP方程

2021.3.10

每日一题

打家劫舍 II

2021.3.11

第5周 第12课 | 动态规划(二)

3.实战题目解析:打家劫舍

DP方程:

  • 下标i表示偷第几个房子 a[i][0,1] 表示从0-i能偷到的max value

0:不偷, 1:偷

// DP方程 a[i] = a[i-1] + nums[i]

思路一: 引入额外的一维空间,表示有没有偷过第[i]个房间。

那么这种情况下的DP方程为: a[i][0] = max(a[i-1][0], a[i-1][1]) a[i][1] = a[i-1] + nums[i]

初始值: a[0][0] = 0 // 第一个房间不偷,金额为0 a[0][1] = nums[0] // 第一个房间被偷,就是第一个房间的值 代码:

class Solution { 
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        int n = nums.length;
        int[][] a = new int[n][2];
        
        a[0][0] = 0;
        a[0][1] = nums[0];
        for (int i = 1; i < n; i++) {
            a[i][0] = Math.max(a[i-1][0], a[i-1][1]);
            a[i][1] = a[i-1][0] + nums[i];
        }
        return Math.max(a[n-1][0], a[n-1][1]);
    }
}

思路二: a[i]:0-i 能偷到的max值,第i个房子可偷或者不偷 0:不偷,1:偷

dp方程:
a[i] = Math.max(a[i-1], nums[i] + a[i-2]);

class Solution {
    public int rob(int[] nums) {
        int n = nums.length;
        if (n <= 1) return n == 0 ? 0 : nums[0];
        int[] dp = new int[n];
        dp[0] = nums[0];
        dp[1] = Math.max(nums[0], nums[1]);
        for (int i = 2; i < n; i++) 
            dp[i] = Math.max(dp[i-1], nums[i] + dp[i-2]);
        
        return dp[n-1];
    }
}