首页 > 其他分享 >Day42 | 动态规划 :选或不选 打家劫舍&&打家劫舍II

Day42 | 动态规划 :选或不选 打家劫舍&&打家劫舍II

时间:2024-11-10 14:45:25浏览次数:3  
标签:nums int 不选 II vector 打家劫舍 dp size

Day42 | 动态规划 :选或不选 打家劫舍&&打家劫舍II

动态规划应该如何学习?-CSDN博客

动态规划学习:

1.思考回溯法(深度优先遍历)怎么写

注意要画树形结构图

2.转成记忆化搜索

看哪些地方是重复计算的,怎么用记忆化搜索给顶替掉这些重复计算

3.把记忆化搜索翻译成动态规划

基本就是1:1转换

文章目录

198.打家劫舍

[198. 打家劫舍 - 力扣(LeetCode)](https://leetcode.cn/problems/integer-break/description/)

思路分析:

树形结构图

image-20241110122753429

先明确一下dp数组/dfs函数的含义,dp[i]就是在前i个房子里面打家劫舍,能得到的最高金额(就是题目要求的)

我们从最后一个房子倒着往前分析子问题

对于一个房子i,我们只有两种方案,选或者不选

选了的话,那我i-1就不能选了

不选的话,那我前i个房子可以得到的最大金额数量就和前i-1个房子可以得到的最大金额数量相等,因为第i个房子没选

所以可以很轻易的得出

dp[i]=max(dp[i-1],dp[i-2]+nums[i]);

即在可能的两种方案中挑选一个最大值

1.回溯 DFS

1.返回值和参数

i是房子编号

nums是房子数字

dfs返回值就是前i个房子里面打家劫舍可以得到的最大金额(和dp数组含义相同)

int dfs(int i,vector<int>& nums)

2.终止条件

可以看到我们递归到0就是叶子结点了,下标0是第一个房子,所以小于0就代表没有房子可以选了,没有房子可以选也就没有金额,就返回0

if(i<0)
	return 0;

3.本层逻辑

如上所说,返回两者的最大值给上层递归函数就好

return max(dfs(i-1,nums),dfs(i-2,nums)+nums[i]);

完整代码:

当然,这是超时的

class Solution {
public:
    int dfs(int i,vector<int>& nums)
    {
        if(i<0)
            return 0;
        return max(dfs(i-1,nums),dfs(i-2,nums)+nums[i]);
    }
    int rob(vector<int>& nums) {
        return dfs(nums.size()-1,nums);
    }
};

2.记忆化搜索

就是搞一个哈希表dp,全都初始化为-1,每次返回前给哈希表dp赋值,碰到不是-1的那就是算过的,那就直接返回计算过的结果,不需要再次递归了

class Solution {
public:
    int dfs(int i,vector<int>& nums,vector<int>& dp)
    {
        if(i<0)
            return 0;
        if(dp[i]!=-1)
            return dp[i];
        return dp[i]=max(dfs(i-1,nums,dp),dfs(i-2,nums,dp)+nums[i]);
    }
    int rob(vector<int>& nums) {
        vector<int> dp(nums.size(),-1);
        return dfs(nums.size()-1,nums,dp);
    }
};

3.1:1翻译为动态规划

1.确定dp数组以及下标的含义

dp数组就是前i个房子里面可以取得的最大金额

下标就是房子编号

2.确定递推公式

忘记了原因的请看思路分析部分

dp[i]=max(dp[i-1],dp[i-2]+nums[i]);

3.dp数组如何初始化

第一种写法,dp数组的下标从0开始,在i=0和i=1我们的递推公式中会有不合法的状态,所以i需要从2开始

那么dp[0]和dp[1]就需要初始化,那么初始化为多少呢?

如果可以根据dp的含义想通如何初始化是最好的,比如前1间房子最大值就是nums[0],前两间房子最大值就是max(nums[0],nums[1])

如果想不通的话,回到回溯法把0和1带进去就完事得出结果就完事

class Solution {
public:
    int dfs(int i,vector<int>& nums)
    {
        if(i<0)
            return 0;
        return max(dfs(i-1,nums),dfs(i-2,nums)+nums[i]);
    }
    int rob(vector<int>& nums) {
        return dfs(nums.size()-1,nums);
    }
};

会得到如下的初始化方案:

		vector<int> dp(nums.size(),0);
        dp[0]=nums[0];
        if(nums.size()>1)
            dp[1]=max(nums[0],nums[1]);
        else
            return dp[0];

第二种写法

dp数组的下标全部都+2(注意nums数组的下标是没变的,此时dp数组的2对应的是nums的0)

这样就避免了下标是负数的情况,完美贴合了dfs回溯的方法

		vector<int> dp(nums.size()+2,0);
        for(int i=0;i<nums.size();i++)
            dp[i+2]=max(dp[i+1],dp[i]+nums[i]);

4.确定遍历顺序

后续结果需要依赖前面的计算结果,故使用从前往后遍历

for(int i=2;i<nums.size();i++)
	dp[i]=max(dp[i-1],dp[i-2]+nums[i]);

完整代码

class Solution {
public:
    int rob(vector<int>& nums) {
        vector<int> dp(nums.size(),0);
        dp[0]=nums[0];
        if(nums.size()>1)
            dp[1]=max(nums[0],nums[1]);
        else
            return dp[0];
        for(int i=2;i<nums.size();i++)
            dp[i]=max(dp[i-1],dp[i-2]+nums[i]);
        return dp[nums.size()-1];
    }
};
class Solution {
public:
    int rob(vector<int>& nums) {
        vector<int> dp(nums.size()+2,0);
        for(int i=0;i<nums.size();i++)
            dp[i+2]=max(dp[i+1],dp[i]+nums[i]);
        return dp[nums.size()+1];
    }
};

213.打家劫舍II

[213. 打家劫舍 II - 力扣(LeetCode)](https://leetcode.cn/problems/integer-break/description/)

分两种情况,考虑是否偷 第一个房子:

如果偷 nums[0],那么 nums[1] 和 nums[nums.size()−1] 不能偷,问题变成从 nums[2] 到 nums[nums.size()−2] 的非环形版本,直接调打家劫舍的代码
如果不偷 nums[0],那么问题变成从 nums[1] 到 nums[nums.size()−1] 的非环形版本,直接调打家劫舍的代码

当然,如果元素数量<=2的话我们的begin+2直接是不合法的,那就做一个特殊处理就好

class Solution {
public:
    int rob1(vector<int> nums) {
        vector<int> dp(nums.size()+2,0);
        for(int i=0;i<nums.size();i++)
            dp[i+2]=max(dp[i+1],dp[i]+nums[i]);
        return dp[nums.size()+1];
    }
    int rob(vector<int>& nums) {
        if(nums.size()==1)
            return nums[0];
        if(nums.size()==2)
            return max(nums[0],nums[1]);
        return max(
            nums[0]+rob1(vector<int>(nums.begin()+2,nums.end()-1)),
            rob1(vector<int>(nums.begin()+1,nums.end())));
    }
};

标签:nums,int,不选,II,vector,打家劫舍,dp,size
From: https://blog.csdn.net/m0_74795952/article/details/143659722

相关文章

  • stm32以太网接口:MII和RMII
    前言使用stm32和lwip进行网络通信开发时,实现结构如下:而MII和RMII就是stm32与PHY芯片之间的通信接口,类似于I2C、UART等。stm32以太网模块有专用的DMA控制器,通过AHB接口将以太网内核和存储器相连。数据发送时,先将数据从存储器以DMA传输到TXFIFO中进行缓冲,然后由MAC内核......
  • 3255. 长度为 K 的子数组的能量值 II
    文章目录问题描述解题思路代码示例复杂度分析问题描述给你一个长度为n的整数数组nums和一个正整数k。一个数组的能量值定义为:如果所有元素都是依次连续且上升的,那么能量值为最大的元素。否则为-1。你需要求出nums中所有长度为k的子......
  • SS241109B. tii(tii)
    SS241109B.tii(tii)题意给你一个\(01\)序列,长度为\(n\le5\times10^5\)。给你一个小数\(p\),要你找出一个区间满足区间\(1\)的个数比区间长度和\(p\)最接近,输出区间的左端点,如果有多个区间输出左端点最小的那个。思路设\(s\)是原序列的前缀和数组,翻译一下题面就是求......
  • 【华为OD技术面试手撕真题】82、环形链表II | 手撕真题+思路参考+代码解析(C & C++ & J
    文章目录一、题目......
  • 42-best-time-to-buy-and-sell-stock-iii 力扣 123. 买卖股票的最佳时机 III
    买卖股票系列【leetcode】40-best-time-to-buy-and-sell-stock力扣121.买卖股票的最佳时机【leetcode】41-best-time-to-buy-and-sell-stock-ii力扣122.买卖股票的最佳时机II【leetcode】42-best-time-to-buy-and-sell-stock-iii力扣123.买卖股票的最佳时机III【le......
  • 240. 搜索二维矩阵 II(中)
    目录题目法一、暴力法二、二分查找法三、Z字形查找题目编写一个高效的算法来搜索mxn矩阵matrix中的一个目标值target。该矩阵具有以下特性:每行的元素从左到右升序排列。每列的元素从上到下升序排列。法一、暴力varsearchMatrix=function(matrix,target){......
  • 代码随想录算法训练营day39 day40| 198.打家劫舍 213.打家劫舍II 337.打家劫舍III
    学习资料:https://programmercarl.com/0198.打家劫舍.html#算法公开课动态规划的打家劫舍系列和股票买卖系列(股票还有贪心算法可解)学习记录:198.打家劫舍(一维dp数组,前n间房子都可偷的情况下的最高金额,每间房子偷数都是由前一间和前两间决定)点击查看代码classSolution(object)......
  • 第二届生成式人工智能与信息安全国际学术会议(GAIIS 2025)
    第二届生成式人工智能与信息安全国际学术会议(GAIIS2025) 会议时间与地点:2025年2月21日至23日,中国杭州。会议主题:围绕“生成式人工智能与信息安全”的最新研究,聚焦AI热点和难点问题,深入剖析信息安全核心技术。大会主席:DongXu,UniversityofMissouri-Columbia,USA姚信......
  • (算法)零钱兑换II————<动态规划>
    1.题⽬链接:518.零钱兑换II2.题⽬描述: 3.解法(动态规划):算法思路:先将问题「转化」成我们熟悉的题型。i.在⼀些物品中「挑选」⼀些出来,然后在满⾜某个「限定条件」下,解决⼀些问题,⼤概率是背包模型;ii.由于每⼀个物品都是⽆限多个的,因此是⼀个「完全背包」问题。接......
  • 107_api_intro_ai_pii-removal
    个人可识别信息(PII)AI去除API数据接口ai/隐私保护基于AI模型自动去除个人识别信息(PII)个人信息保护/AI模型。1.产品功能基于自有专业模型进行PII自动去除高效处理敏感信息全接口支持HTTPS(TLSv1.0/v1.1/v1.2/v1.3);全面兼容AppleATS;全国多节点C......