2022-07-28 09:49阅读: 26评论: 0推荐: 0

力扣-198-打家劫舍

直达链接

2022/10/28 重做

要求是不触发报警,即:对数组中的元素不相邻选中的情况下,能够获得的最大和

int rob(vector<int>& nums) {
// 定义一个dp数组dp[i]代表截至i(包括)能够获得的最大金额
// 对于任意nums[i],如果这户要偷,则上一户一定不偷dp[i] = dp[i-2]+nums[i]
// 如果这户不偷,dp[i] = dp[i-1]
int n = nums.size();
vector<int> dp(n + 1);
// 照上面的看来我至少要初始化2个元素
dp[0] = 0, dp[1] = nums[0];
for (int i = 2; i <= n; i++) dp[i] = max(dp[i - 1], dp[i - 2] + nums[i-1]);
return dp[n];
}

然后做空间优化,这里需要三个变量,然后这里循环也可以改一下,看着有点别扭

int rob(vector<int>& nums) {
int prepre = 0, pre = nums[0], cur = nums[0];
for (int i = 1; i < nums.size(); i++) {
cur = max(pre, prepre + nums[i]);
prepre = pre;
pre = cur;
}
return cur;
}

我再想这个题有没有可能就是比奇数序列和偶数序列哪个大

int rob(vector<int>& nums) {
int odd = 0,even = 0;
for (int i = 0; i < nums.size(); i++) {
if (i % 2) odd += nums[i];
else even += nums[i];
}
return max(odd,even);
}

哈哈,好吧,不是这样的

思路

当我们打劫到一个房子i的时候,有两种选择

  1. 不打劫这栋房子,那么总收益就是dp[i-1],即打劫到上一栋房子的收益
  2. 打劫这栋房子,同时有不能打劫相邻房子的限制,则总收益为:dp[i]+dp[i-2]

状态转移方程为:dp[i]=max(dp[i-1],input[i]+dp[i-2])

代码

class Solution {
public:
int rob(vector<int>& nums) {
// nums.length>=1,就是说一定不为空,否则就要判断
int len = nums.size();
// 分析初始值:如果只有1栋房子,那么最高收益一定就是nus[0]
// if (len == 1) return nums[0];
// 这句不需要,下面的代码能包含这种情况,但是或许能剪枝?跑一跑还是去掉效率高一点
int pre1 = 0, pre2 = 0, cur;
// 如果是第二栋,是第一栋与第二栋的最大值,就可以开始
for (int i = 0; i < len; ++i) {
// 这里<len主要影响的是nums的下标
cur = max(pre1, pre2 + nums[i]);
pre2 = pre1;
pre1 = cur;
}
return cur;
}
};

效率很不错

本文作者:YaosGHC

本文链接:https://www.cnblogs.com/yaocy/p/16527468.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   YaosGHC  阅读(26)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起