Leetcode198. 打家劫舍--动态规划

题目

在这里插入图片描述

动态规划

动态规划的四个解题步骤是;

  • 定义子问题
  • 写出子问题的递推关系
  • 确定DP数组的计算顺序
  • 空间优化(可选)

步骤一:定义子问题
子问题和原问题相似,但规模较小。本题中的子问题就是“从k个房子中能偷到的最大金额”,用f(k)表示
在这里插入图片描述
步骤二:写出子问题的递推关系

假设一共有n个房子,每个房子的金额分别是H0,H1,…Hn-1,子问题f(k)表示从前k个房子(即H0,H1,…Hk-1)中能偷到的最大金额。那么,偷k个房子有两种偷法:
在这里插入图片描述
k个房子中最后一个房子是Hk-1,如果不偷这个房子,那么问题就变成在前k-1个房子中偷盗的最大的金额,也就是子问题f(k-1)。如果偷这个房子,那么前一个房子Hk-2就不能偷,其他的房子不受影响。那么问题就变成在前 k-2k−2 个房子中偷到的最大的金额。两种情况中,选择金额较大的一种结果。
在这里插入图片描述

步骤三:确定DP数组的计算顺序

每个 f(k) 依赖 f(k-1) 和 f(k-2)。也就是说,dp[k] 依赖 dp[k-1] 和 dp[k-2],如下图所示。
在这里插入图片描述
DP 数组中的依赖关系都是向右指的,DP 数组的计算顺序就是从左向右。这样我们可以保证,计算一个子问题的时候,它所依赖的那些子问题已经计算出来了。

class Solution:
    def rob(self, nums: List[int]) -> int:
        if len(nums)==0: return 0
        dp=[0 for _ in range(len(nums)+1)]
        dp[0]=0
        dp[1]=nums[0]
        for k in range(2, len(nums)+1):
            dp[k]=max(dp[k-1], nums[k-1]+dp[k-2])
        return dp[len(nums)]
class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.size()==0){
            return 0;
        }
        if (nums.size()==1){
            return nums[0];
        }
        int l=nums.size();
        vector<int> dp(l, 0);
        dp[0]=nums[0];
        dp[1]=max(dp[0], nums[1]);
        for (int i=2; i<l; i++){
            dp[i]=max(dp[i-1], dp[i-2]+nums[i]);
        }
        return dp[l-1];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值