LeetCode198--打家劫舍
解:
这又是一道经典的数组动态规划题,诸如青蛙跳楼梯,爬楼梯等动态规划题一样。换汤不换药,不离其综,不变其魂!
还是那句话,想要最后的答案,动态规划必须回到最开始的问题,分析初始情况。
1、假设有 i 家待偷,第 i 家财物为 nums[i-1]。则我偷得的最大财物为dp[i-1];
2、i = 1:我偷得最大财物 dp[0] = nums[0];
3、i = 2:我偷得最大财物为 dp[1] = Math.max(nums[0],nums[1]);
4、关键问题,i = 3:我想,第3家我到底值不值得去偷?偷了第3家我就没办法偷第2家,但是可以偷第1家。
也就是:(第3家财物 + 第1家财物 ) 会不会大于 (第2家财物)?
5、同理、i = n:我想,第n家我到底值不值得去偷?偷了第n家我就没办法去偷第n-1家,但是第n-1家以前的肥羊,我还是能偷到最大值。也就是:(第n家财物 + 第n-1家以前所有能偷到的最大财物) 会不会大于 (第n家以前所有能偷到的最大财物)
6、用 dp[n-1] 记录当总共有n家肥羊时我能偷到得最大财物。
7、返回dp[n-1]即可.
代码实现:
public int rob(int[] nums) {
//排除特殊情况,没肥羊,和只有一头肥羊
if (nums.length == 0)return 0;
if (nums.length == 1)return nums[0];
//建立数组:角标x代表中共有x+1家肥🐏时,dp[x]就是能偷到的最大财物
int [] dp = new int[nums.length];
//初始化
dp[0] = nums[0];
dp[1] = Math.max(nums[0],nums[1]);
//遍历赋值,相互影响,逐步递进
for (int i = 2; i < nums.length; i++){
dp[i] = Math.max(dp[i-1],dp[i-2] + nums[i]);
}
//返回战利品
return dp[nums.length-1];
}
总结:
1、动态规划问题,一定要关注初始结果,逐步递进。
2、因为这种问题它的每个结果都不是独立存在的,它与前一个结果息息相关,前一个结果不同,那么会影响当前结果。
3、不离其综,不变其魂!