LeetCode打家劫舍(dp)

题目描述在这里插入图片描述

这题一看就知道得用动态规划做,本来在学校是学过的,但缺少实践,理论知识也忘得差不多了,看到这题还是不知道该怎么用dp解,只能翻看题解,理解后独立写出代码
dp方程如下:

dp[i] = max(dp[i-2] + nums[i] , dp[i-1])
  • dp[i]表示偷了 i 家时,获得的最大收益
  • nums[i]表示当前准备偷的房屋有多少钱

理解下来就是:偷了 i 家后,我所获得的最大收益要么等于偷完上一家的收益(不偷当前这家),要么等于偷完i-2家和当前房屋的金额之和(偷当前这家)

int rob(vector<int>& nums) {
    
    
        if(nums.size() == 0) return 0;//没有房屋
        if(nums.size() == 1) return nums[0];//只有一间房屋
        int len = nums.size();
        vector<int> dp(len);
        dp[0] = nums[0];//偷了第0家
        for(int i=1; i<len; i++){
    
    
            if(i == 1){
    
    
                dp[i] = max(nums[i] , dp[i-1]);//偷第1家
            }else{
    
    
                dp[i] = max(dp[i-2] + nums[i] , dp[i-1]);
            }
        }
        return dp[len-1];
    }

在这里插入图片描述
优化一下,可以去掉dp数组。由于dp数组只是记录了当前获取的最大收益,找个变量记录一下即可。当然上述代码中的dp[i-2]也得用变量记录

int rob(vector<int>& nums) {
    
    
        if(nums.size() == 0) return 0;
        if(nums.size() == 1) return nums[0];
        if(nums.size() == 2) return nums[0] > nums[1] ? nums[0] : nums[1];//只有两个房屋时
        int len = nums.size();
        int cur_profit;
        int pre_2 = nums[0];//dp[i-2]
        int pre_1 = nums[0] > nums[1] ? nums[0] : nums[1];//dp[i-1]
        for(int i=2; i<len; i++){
    
    
            cur_profit = max(pre_2 + nums[i] , pre_1);
            pre_2 = pre_1;
            pre_1 = cur_profit;
        }
        return cur_profit;
    }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42500831/article/details/105196927
今日推荐