代码随想录|day48| 动态规划part09● 198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

198.打家劫舍

链接:代码随想录

这里我还以为要用01背包。。。。

用的是逻辑而不是套路。让人想起爬楼梯那道题。这里我犯了初始化错误,错误在注释中写出。

正确做法:

class Solution {
/*
比作跳台阶的话,这个只能一次跳两个台阶的感觉.
1、每个元素只能使用1次,所以0、1背包
2、
dp[j]代表从0---j房间能偷到的最大金额(包括j)
dp[j]=max(dp[j-1],dp[j-2]+nums[i])
*/
public:
    int rob(vector<int>& nums) {
        int n=nums.size();
         if (n == 0) return 0;
        if (n== 1) return nums[0];
        vector<int>dp(n,0);
        /*
        初始化错了,因为我们算的是闭区间,是包含当前的nums[j]的
        dp[0]=0;
        dp[1]=nums[0];*/

        //dp[0] 一定是 nums[0],dp[1]就是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1]);
        dp[0]=nums[0];
        dp[1]=max(nums[0],nums[1]);
        for(int j=2;j<n;j++)
        {
            dp[j]=max(dp[j-1],dp[j-2]+nums[j]);
        }
        return dp[n-1];


    }
};

213.打家劫舍II

链接:代码随想录

 

 

 没想到做法,感觉这道题只能靠认识,自己想不出来。

看着懵,暂时不想做

 

337.打家劫舍 III 

链接:代码随想录

视频链接:动态规划,房间连成树了,偷不偷呢?| LeetCode:337.打家劫舍3_哔哩哔哩_bilibili

 

 

啥也不会,但是视频讲的太好啦!!! 树形dp第一天入门

 最终代码自己写出来了,很满足。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */

 /*
 树形dp的入门题目,因为是在树上进行状态转移,我们在讲解二叉树的时候说过递归三部曲,那么下面我以递归三部曲为框架,其中融合动规五部曲的内容来进行讲解。

 对于每个节点,都有偷和不偷两种状态,要记录每个节点偷时的最大值和不偷时的最大值。
 所以对于每个节点,都有滚动数组vector<int>dp(2,0);
                      dp[0]代表该节点不偷的情况下最大值;
                      dp[1]代表该节点偷的情况下最大值;
 
 后序遍历,从下往上遍历。则对于本状态,下一层是上一个状态。
 2、递推公式
 对于一个节点,
 如果他被偷,则上一个状态(在这里从下往上,是左右节点)必然不能被偷,
         本节点node的dp[1]=node->val+nodeleft的dp[0]+noderight的dp[0];
 如果他不被偷,则上一个状态可以被偷也可以不被偷,只需要看哪个大。而且左右节点必被相加
        本节点node的dp[0]=max(nodeleft的dp[0],nodeleft的dp[1])+
                         max(noderight的dp[0],noderight的dp[1])
 
 
 3、初始值
 后序遍历,从下往上遍历。则对于示例1的叶子节点,{0,3}

 */
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};
        }
        
        vector<int>left=dfs(root->left);
        vector<int>right=dfs(root->right);
        //本节点不被偷
        int val_not_rob=max(left[0],left[1])+max(right[0],right[1]);
        
        //本节点被偷,则上一个状态必定不被偷
        int val_rob=root->val+left[0]+right[0];


        return {val_not_rob,val_rob};
    }

};

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值