Leetcode House强盗

时间:2016-09-17 00:45:39

标签: algorithm dynamic-programming

我在leet代码上尝试House Robber问题(dp问题)。 来自用户GYX的这个解决方案看起来简单而优雅。

   int rob(vector<int>& num) {
   int n = num.size();
        if (n==0) return 0;
        vector<int> result(n+1,0);
        result[1] = num[0];
        for (int i=2;i<=n;i++){
            result[i] = max(result[i-1],result[i-2]+num[i-1]);
        }
        return result[n];
   }

但我无法理解逻辑。请帮助我解决逻辑,以及如何处理这样的问题?

3 个答案:

答案 0 :(得分:6)

基本上答案是f(n) = max( f(n-1), f(n-2) + arr[n] ),你问为什么。

假设这个数组arr = [9,1,7,9]f(n)是函数。

当数组仅为[9] 时,您的最高f(0)将为arr[0]

当数组为[9,1] 时,您的最高f(1)max(arr[0], arr[1])

当数组为[9,1,7] 时,如果您选择7,则无法选择1 {{1} }}。但是,如果您未选择f(n-2) + arr[n],则最高7将与f(2) f(1)相同。

当数组为f(n-1) 时,您需要同时删除1&amp; 7并选择9,9。[9,1,7,9]等式满足这种情况。

答案 1 :(得分:2)

假设我将金额存储在house[k]中的第k个房子中。

假设现在我存储了max[k]中从前k个房屋(仅限第一个k)中掠夺的最大金额。

现在考虑没有房子,所以max[0]=0

现在只考虑第一宫,max[1] =房屋1中的金额

现在考虑前两个房子,

max[2] = {或max[1](暗示我们选择抢劫房屋1)或(房屋2中的金额+我抢劫的最高金额,直到房子位于我当前房屋前2个地方)} = {max(max[1],house[2]+max[0])}

同样对于前3个房屋,max[3]=max(max[2],house[3]+max[1])

观察这一趋势,可以制定max[k]=max(max[k-1],house[k]+max[k-2])。这个值计算到最后没有房子的时候,我们得到了这些前n个房子可以抢劫的最高金额。

只有当你之前有过一些练习和熟悉之后,DP问题就会出现问题,这总是有帮助的。

答案 2 :(得分:0)

看看这个简单的递归代码。乍看之下,很难解决DP中解决的问题。您应该始终从性能低下的递归代码开始努力。这是代码的不同版本:

p = [0, 1, 2, 3, 1, 2, 3, 1, 2, 5, 8, 2]
def R(i):
    if i == 1 or i == 2:
        return i
    else:
        return max(p[i] + R(i - 2), R(i - 1))

print(R(11))

如果您想提高效率,这也很容易记住。