直觉背后这个DP的基础案例

时间:2017-11-03 19:45:34

标签: c++ dynamic-programming

我正在尝试解决以下DP问题:

  

给出一个代表每个房子的金额的非负整数列表,确定今晚可以抢劫的最大金额而不警告警察。你不能抢劫邻近的房屋,因为这样做会提醒警方。

给出的解决方案之一是:

class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.empty())
            return 0;

        if(nums.size()==1)
            return nums[0];

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

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

        return dp[nums.size()-1];
    }
};

有人可以指出dp[1]初始化背后的直觉:

dp[1] = max(nums[0], nums[1]);

我将其初始化为dp[1] = nums[1]。但是,它会在[3,1,4,10]等测试用例中中断。当我们将其初始化为max(nums[0], nums[1]);时,我们排序将输入数组更改为[3,3,4,10]?它如何帮助我们达到最终(正确)解决方案?

注意:问题来自here

编辑:指南是否建议考虑我们的主要DP公式,同时对基本案例进行硬编码以解决这些问题?

1 个答案:

答案 0 :(得分:1)

为了最大化您可以抢劫的金额,您必须从第一宫或第二宫开始抢劫。你不能同时抢夺它们,因为它们是相邻的,这不符合给定的条件。

你不能抢劫他们,因为你会错过一个房子而且会导致一个不是全局最大值的值。

初始化可以被视为“你可以从房子0开始抢劫并进入房屋1(含)的最大金额”。你的初始化说明你可以从前两个房子抢劫的最大值只有1(不是3,因为它必须是),这是假的,导致错误的最大值。