标签:strong 动态 影响 title 情况 为什么 数组 动态规划 方法
题名:打家劫舍
描述:
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
? 偷窃到的最高金额 = 1 + 3 = 4 。
具体描述请查看Leetcode相关网页:https://leetcode-cn.com/problems/house-robber/
偷到第 n 家后会有 F(n) 的金额,其中 F(n) = max( F(n - 2), F(n - 3) ) + nums[n - 1]
(因为不能偷相邻人家的钱)
那么为什么只要比较第 F(n - 2)
和 F(n - 3)
就够了呢?不是还有 F(n - 4)、F(n - 5).....
吗?
因为 F(n - 2) = max( F(n - 4), F(n - 5) ) + nums[n - 3]
; nums中存储的值必定大于等于0,所以 F(n - 2) >= max( F(n - 4), F(n - 5) )
,同理
F(n - 3) >= max( F(n - 5), F(n - 6) )
;所以只要比较 F(n - 2)
和 F(n - 3)
就可以了~
代码如下:
//递推式: F(n) = max( F(n - 2), F(n - 3) ) + nums[n - 1];
int rob(vector<int>& nums) {
int n = nums.size();
if(n == 0) return 0;
if(n == 1) return nums[0];
if(n == 2) return max(nums[0], nums[1]);
if(n == 3) return max(nums[0] + nums[2], nums[1]);
// 从F(4) = max( F( 2 ), F( 1 ) ) + nums[3];开始递推
int ans, a = max(nums[0], nums[1]), b = nums[0],
c = max(nums[0] + nums[2], nums[1]);// a 用来存F(n - 2), b用来存F(n - 3), c用来存F(n - 1)
for(int i = 3;i < n;i++){
ans = max(a, b) + nums[i];
b = a;
a = c;
c = ans;
}
return max(ans, a);// 比较F(n)和F(n - 1),返回大的那个
标签:strong 动态 影响 title 情况 为什么 数组 动态规划 方法
原文地址:https://www.cnblogs.com/Codroc/p/12491445.html