leetcode 198 打家劫舍
在一个数组中,不能选择连续的2个数,问最大可以取值是多少。
这里有两种dp的思路:
dp[i]表示抢劫第i间房屋,最多可以抢到的钱。它有两个来源 dp[i-2],dp[i-3]。我们取其中大的值。
有的同学可能要问了,为什么不考虑dp[i-4] dp[i-5]这些更往前的房子?
因为i-5, i-4, i-3,i-2, i-1, i,如果直接从 i-4, i-5跳过来,一定会小于 i-3, i-2的,因为他们都是非负数。
于是我们有状态转移方程:
dp[i] = max(dp[i-2],dp[i-3])+num[i]
边界条件为:
dp[0]=num[0]
dp[1]=num[1]
dp[2] = num[2]+num[0]
最后我们取 max(dp[len-1],dp[len-2])就可以了。
public static int rob(int[] nums) { int len = nums.length; if(len==0) return 0; int[] dp = new int[len]; if(len==1) return nums[0]; else if(len==2) return Math.max(nums[0],nums[1]); else if(len==3) return Math.max(nums[1],nums[0]+nums[2]); else{ dp[0]=nums[0]; dp[1]=nums[1]; dp[2]=nums[2]+nums[0]; for(int i=3;i<len;i++){ dp[i]=Math.max(dp[i-2],dp[i-3])+nums[i]; } } return Math.max(dp[len-1],dp[len-2]);
看了一眼题解,有另一种dp思路:
dp[i]表示对第i个房屋,可以抢的最大值。那么对于第i个房屋,有两种选择:抢和不抢。
如果抢:dp[i]=num[i]+dp[i-2]
如果不抢 dp[i]=dp[i-1]
于是又状态转移方程:
dp[i]=max(dp[i-2]+num[i],dp[i-1])
边界条件为:
dp[0]=num[0]
dp[1] = max(num[0],num[1])
public static int rob2(int[] nums) { int len = nums.length; if(len==0) return 0; int[] dp = new int[len]; if(len==1) return nums[0]; else if(len==2) return Math.max(nums[0],nums[1]); else{ dp[0]=nums[0]; dp[1]=Math.max(nums[1],nums[0]); for(int i=2;i<len;i++){ dp[i]=Math.max(dp[i-2]+nums[i],dp[i-1]); } } return Math.max(dp[len-1],dp[len-2]);