又是抽象的dp
一开始误以为是跳着偷,隔一间偷一间,被自己蠢到了
动态转移方程为:
dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1])
dp[i - 2] + nums[i] 表示偷第i家,再加上前i - 2家以来积累的赃款
dp[i - 1] 表示不偷第i家,表示前i - 1家以来积累的赃款
边界条件
dp[0] = nums[0] 只有一家可偷
dp[1] = Math.max(nums[0], nums[1]) 只有两家可偷,偷最多的
下图中偷和不偷[0, 1]都初始化为7。
绿色表示偷,黄色表示不偷,蓝色表示当前可以偷最多钱的路径。
👇 偷3:3加上i - 2中钱最多的,3 + 7 = 10
不偷3:i - 1中钱最多的,7
👇偷9:9加上i - 2中钱最多的,9 + 7 = 16
不偷9:i - 1中钱最多的,10
👇偷2:2加上i - 2中钱最多的,2 + 10 = 12
不偷2:i - 1中钱最多的,16
public int rob(int[] nums) {
int len = nums.length;
if (len == 1) {
return nums[0];
}
int[] dp = new int[len];
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for (int i = 2; i < len; i++) {
dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
}
return dp[len - 1];
}