力扣-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的时候,有两种选择
- 不打劫这栋房子,那么总收益就是dp[i-1],即打劫到上一栋房子的收益
- 打劫这栋房子,同时有不能打劫相邻房子的限制,则总收益为: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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步