首页 > 其他分享 >198. 打家劫舍

198. 打家劫舍

时间:2024-04-09 22:11:23浏览次数:18  
标签:return 198 nums int max memo dfs 打家劫舍

题目链接:

本题考察动态规划。

实现一、递推

\(f[i]\) 表示考虑下标从 \(0 \sim i\) 的房屋最多能抢劫到的金额。
思考状态转移时考虑第 \(i\) 个房屋抢或不抢。
由于不能抢劫相邻的房屋,若抢了 \(i\) 个房屋,则第 \(i-1\) 个房屋就不能抢,再抢只能从 \(i-2\) 开始考虑,即 \(\rm f[i-2]+nums[i]\)。若不抢第 \(i\) 个房屋,则从 \(i-1\) 开始考虑,即 \(\rm f[i-1]\)。

class Solution {
public:
    static const int N = 110;
    int f[N];
    int rob(vector<int>& nums) {
        int n = nums.size();
        if (n == 1) return nums[0];
        if (n == 2) return max(nums[0], nums[1]);//由于房屋个数未知,而状态转移时会用到i-2,i从2开始循环迭代,因此需要特判一下~
        f[0] = nums[0];
        f[1] = max(nums[0], nums[1]);
        for (int i = 2; i < n; i++) {
            f[i] = max(f[i - 2] + nums[i], f[i - 1]);
        }
        return f[n - 1];
    }
};

若不想特判,使得代码看起来更加简洁,可以考虑把 \(f\) 数组的每个下标值都加上 \(2\)。

class Solution {
public:
    static const int N = 110;
    int f[N];
    int rob(vector<int>& nums) {
        int n = nums.size();
        for (int i = 0; i < n; i++) {
            f[i + 2] = max(f[i + 1], f[i] + nums[i]);
        }
        return f[n + 1];
    }
};

实现二、记忆化搜索

class Solution {
public:
    int rob(vector<int>& nums) {
        int n = nums.size();
        vector<int> memo(n, -1);//-1表示没有计算过
		
	//dfs(i)表示从nums[0]到nums[i]最多能偷多少
        function<int(int)> dfs = [&] (int i) -> int {
            if (i < 0) return 0;//递归边界(没有房子)
            if (memo[i] != -1) return memo[i];//之前计算过
            return memo[i] = max(dfs(i - 1), dfs(i - 2) + nums[i]);
        };
        return dfs(n - 1);//一直到最后一个房子
    }
};

标签:return,198,nums,int,max,memo,dfs,打家劫舍
From: https://www.cnblogs.com/pangyou3s/p/18124975

相关文章

  • 双数列-力扣-打家劫舍2
    一个专业的小偷,计划偷窃一个环形街道上沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。给定一个代表每......
  • asm增加磁盘由于Bug19874632导致磁盘块头丢失ORA-15196
    数据库日志,磁盘组突然被dismount掉:TueApr0210:39:152024Errorsinfile/u01/app/oracle/diag/rdbms/orcl/orcl1/trace/orcl1_lgwr_150319.trc:ORA-00345:redologwriteerrorblock222293count1ORA-00312:onlinelog5thread1:'+DB/orcl/onlinelog/group_5.2......
  • 洛谷题单指南-图的基本应用-P1983 [NOIP2013 普及组] 车站分级
    原题链接:https://www.luogu.com.cn/problem/P1983题意解读:由于“如果这趟车次停靠了火车站x,则始发站、终点站之间所有级别大于等于火车站x的都必须停靠”。因此,在始发站和终点站之间,能停靠的车站都是级别较高的,没有停靠的车站都是级别较低的,计算最少有多少个不同级别。解题思路:......
  • LeetCodeHot100 动态规划 70. 爬楼梯 118. 杨辉三角 198. 打家劫舍 279. 完全平方
    70.爬楼梯https://leetcode.cn/problems/climbing-stairs/description/?envType=study-plan-v2&envId=top-100-likedpublicintclimbStairs(intn){if(n<=1)returnn;int[]dp=newint[n+1];dp[1]=1;dp[2]=2;......
  • Offer必备算法15_简单多问题dp_八道力扣题(打家劫舍+买卖股票)
    目录①力扣LCR089.打家劫舍解析代码②力扣213.打家劫舍II解析代码③力扣740.删除并获得点数解析代码④力扣LCR091.粉刷房子解析代码⑤力扣309.买卖股票的最佳时机含冷冻期状态机分析解析代码⑥力扣714.买卖股票的最佳时机含手续费状态机分析解析代码⑦......
  • P4198 楼房重建
    P4198楼房重建求从\((0,0)\)往上看能看到多少栋没被挡住的楼房,带修改。对于带修改的题目,我们需要快速维护,就需要用到数据结构。这时候通过直觉可以想到,问题是可以分为子问题然后合并得到的,所以我们考虑线段树。观察到能被看到的楼房,从左到右斜率递增,即我们需要维护斜率递增......
  • (47/60)打家劫舍、打家劫舍Ⅱ、打家劫舍Ⅲ
    day47打家劫舍leetcode:198.打家劫舍动态规划代码实现/*偷到下标为i的最大金额数为dp[i]偷i、不偷i:dp[i]=max(dp[i-2]+nums[i],dp[i-1]);dp[0]=nums[0];dp[1]=max(nums[0],nums[1]);正序遍历*/classSolution{public:introb(vector<int>&nums){......
  • Gym 101981-I Magic Potion 题解
    传送门题意:有\(n\)个勇者和\(m\)个怪物,第\(i\)个勇者有一个可杀怪物集合\(M_i\),每个勇者只能杀各自\(M_i\)中的一个怪物。但是你有\(k\)瓶魔药,每一瓶都可以让一个勇者多杀一个\(M_i\)中的怪物。但是每个勇者只能吃一瓶药。问最多能杀多少个。考虑让勇者和怪物匹......
  • 代码随想录算法训练营第四十七天| ● 198.打家劫舍 ● 213.打家劫舍II ● 337.打家
    打家劫舍 题目链接:198.打家劫舍-力扣(LeetCode)思路:每一家的最大收益来源只有两个,一个是这家不偷,那么最大收益等于从上一家出来的最大收益,另一个是偷这一个家,因此最大收益等于从上上一家出来的最大收益加这一家的收益。classSolution{public:introb(vector<int>&nu......
  • 代码随想录算法训练营第四十七天 | 337.打家劫舍III,213.打家劫舍II ,198.打家劫舍
     198.打家劫舍 已解答中等 相关标签相关企业 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一......