House Robber 基本动态规划:一维--力扣101算法题解笔记

7.2House Robber 基本动态规划:一维

题目描述

假如你是一个劫匪、并且决定抢劫一条街道上的房子。每个房子内的钱财数量都不同。但是如果你抢了两栋相邻的房子,就会触发警报机关。求在不触发机关的情况下,最多可以抢劫多少钱。

输入输出样例

Input :[2, 7, 9, 3, 1]

Output:12

题解

定义一个数组dp,dp[i]表示抢劫到第i个房子时,可以抢劫的最大数量。要考虑dp[i],此时可以抢劫的最大数量有两种可能,一种我们选择不抢劫这个房子,此时累计的金额就得-1,也就是dp[i-1];另一种选择是抢劫这个房子,因为不能抢劫第i-1个房子,这样会触发警报,那么此前累积的最大金额只能是dp[i-2],所以得到一个状态转移方程为dp[i]=max(dp[i-1],nums[i-1],+dp[i-2])

我们利用这个状态方程就可以把逻辑问题变成数学问题然后设计算法解决了

"因为不能抢劫第i-1个房子,这样会触发警报,那么此前累积的最大金额只能是dp[i-2]"

对这句话的解释:

既然第 i-1 个房子不抢,那 "抢劫到第 i 个房子" 的最大金额,就等于 "第 i 个房子的金额" + "抢劫到第 i-2 个房子时的最大金额";这里的 "抢劫到第 i-2 个房子时的最大金额" 就是 dp[i-2] ------ 因为 dp [i-2] 已经包含了 "抢劫到第 i-2 个房子时能拿到的所有最优情况"(不管第 i-2 个房子抢没抢,它都是到 i-2 为止的最大值)

当然,这题目跟上一个一样,还是只用到pre1和pre2,两个数组,直接简化就完事了。

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

int rob(vector<int>& nums) {
    if (nums.empty())    return 0;
    int n = nums.size();
    if (n == 1)  return nums[0];
    int pre2 = 0, pre1 = 0, cur;
    for (int i = 0; i < n; ++i) {
        cur = max(pre2 + nums[i], pre1);
        pre2 = pre1;
        pre1 = cur;
    }
    return cur;
}

int main() {
    vector<int> nums = { 2, 7, 9, 3, 1 };
    cout << rob(nums) << endl;
    return 0;
}
相关推荐
掘根1 小时前
【C++STL】红黑树(RBTree)
数据结构·c++·算法
我笑了OvO1 小时前
常见位运算及其经典算法题(1)
c++·算法·算法竞赛
Zevalin爱灰灰1 小时前
方法论——如何设计控制策略架构
算法·架构·嵌入式
wostcdk1 小时前
基础算法学习1
算法
Yzzz-F1 小时前
2026牛客寒假算法基础集训营1
算法
野犬寒鸦1 小时前
Java8 ConcurrentHashMap 深度解析(底层数据结构详解及方法执行流程)
java·开发语言·数据库·后端·学习·算法·哈希算法
m0_531237171 小时前
C语言-函数递归练习
算法
日光倾1 小时前
【Vue.js 入门笔记】Git入门
笔记·git
回敲代码的猴子1 小时前
2月18日打卡
算法