当前位置: 首页 > article >正文

198.213.337.打家劫舍

198.213.337.打家劫舍

198.打家劫舍

思路:动态规划,有点类似122.股票II

dp[i] [0]表示第i个房间为止偷到的最大金额 且第i天没偷

dp[i] [0]表示第i个房间为止偷到的最大金额 且第i天偷了

初始化dp[0] [0]=0, dp[0] [1]=nums[0]

从第二间屋开始遍历,金额有两种情况:

1.今天偷:昨天一定没偷 dp[i-1][0]+nums[i]

2.今天不偷:两种情况取最大值

(1)昨天偷了:dp[i-1][1]

(2)昨天也没偷:dp[i-1][0]

dp[i][0]=max(dp[i-1][1],dp[i-1][0]);

代码:

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

213.打家劫舍II

思路:动态规划

对于198题多了一个圈的限制,即初始化的时候做限制,从第二间屋开始动态规划:

(1)选了dp[1][0]第一天没偷做开头,

那么最后一天偷不偷都可,取max(dp[n-1][1],dp[n-1][0])

初始条件:第二天偷or不偷都可以, dp2[1][0]=0 dp2[1][1]=nums[1]

(2)选了dp[1][1]第一天偷了做开头

那么最后一天一定没偷,只能取dp[n-1][0]

初始条件:第二天一定没偷, dp[1][0]=nums[0] dp[1][1]=nums[0]

再看情况1,2哪个更大

另注意:环形偷窃要注意越界,只有一个房子直接return

代码:

class Solution {
public:
    int rob(vector<int>& nums) {
        int n=nums.size();
        vector<vector<int>>dp (n,vector<int>(2));
        vector<vector<int>>dp2 (n,vector<int>(2));
        int a=0;
        int b=0;
        //环形偷窃要注意越界,只有一个房子直接return
        if(n==1)
        return nums[0];
        //第一天偷,第二天不偷
        dp[1][0]=nums[0];
        dp[1][1]=nums[0];
        for(int i=2;i<n;i++){
            //今天不偷
            dp[i][0]=max(dp[i-1][1],dp[i-1][0]);
            //今天偷
            dp[i][1]=dp[i-1][0]+nums[i];
        }
        a=dp[n-1][0];//第一天偷 最后一天只能不偷
        //第一天不偷,第二天偷or不偷
        dp2[1][0]=0;
        dp2[1][1]=nums[1];
        for(int i=2;i<n;i++){
            //今天不偷
            dp2[i][0]=max(dp2[i-1][1],dp2[i-1][0]);
            //今天偷
            dp2[i][1]=dp2[i-1][0]+nums[i];
        }
        b=max(dp2[n-1][1],dp2[n-1][0]);
        return max(a,b);
    }
};

337.打家劫舍III

思路:二叉树递归+动态规划

对于当前结点node有两种情况:

(1)node偷:左右孩子一定不偷

(2)node不偷:左偷 or 不偷最大值+右偷 or 不偷最大值

最终返回根结点root 偷 or 不偷最大值

使用一个vector<int> dp实际上每次只使用size为2的vector,递归时返回当前结点{不偷,偷}能得到的最大和

代码:

class Solution {
public:        
    int rob(TreeNode* root) {
        vector<int>dp=dfs(root);
        return max(dp[0],dp[1]);
    }
    vector<int> dfs(TreeNode* root){
        if(root==nullptr)
        return {0,0};
        //[0]是不偷,[1]是偷
        vector<int> left=dfs(root->left);
        vector<int> right=dfs(root->right);
        //当前root偷,左右孩子不偷最大值的和
        int tou=left[0]+right[0]+root->val;
        //当前root不偷,左右孩子偷or不偷最大值的和
        int butou=max(left[1],left[0])+max(right[1],right[0]);
        return {butou,tou};
    }
};

http://www.kler.cn/a/460632.html

相关文章:

  • Redis的生态系统和社区支持
  • Java 代码编译和解析方法信息
  • Leetcode 3405. Count the Number of Arrays with K Matching Adjacent Elements
  • Linux 服务器启用 DNS 加密
  • 攻防靶场(29):目录权限和文件权限 ICMP
  • el-pagination 为什么只能展示 10 条数据(element-ui@2.15.13)
  • MySql find_in_set 函数
  • 数据仓库: 9- 数据仓库数据治理
  • KubeOS
  • java基于ThreadLocal实现单例模式
  • Android 系统 AlertDialog 系统层深度定制
  • 基于AT89C51单片机的可暂停八路抢答器设计
  • 试用ChatGPT的copilot编写一个程序从笔记本电脑获取语音输入和图像输入并调用开源大模型进行解析
  • 【一起python】银行管理系统
  • linux上使用cmake编译的方法
  • ArrayList 和LinkedList的区别比较
  • 酒后饮品选择指南:科学缓解不适
  • 2024年年度总结
  • Pyqt5学习(学习中)
  • LoRaWAN协议在基于低地球轨道的大规模机器类通信架构中的无缝集成
  • 游戏引擎学习第64天
  • 柱状图中最大的矩形 - 困难
  • 微服务-Sentinel新手入门指南
  • UE5在蓝图中使用VarestX插件访问API
  • html+css网页制作 美食 美食每刻4个页面
  • MapReduce相关概念(自用)