LeetCode198:打家劫舍

LeetCode198: 打家劫舍

    • 题目说明
    • 题目分析
    • 代码

题目说明

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

示例 1:

输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。

示例 2:

输入: [2,7,9,3,1]
输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。

题目分析

补上前两天的作业!
类似这种求得到的最大值,一般会考虑贪心算法或者动态规划(DP)。而动态规划往往是将大的问题分成相似的小模块,求得小模块最优值,得到最终最优值。显然,这道题可以用dp,而且是一维dp问题。而动态规划问题的关键就是找状态转移方程!
动态规划从大到小分解,比如我们要求 n 处的最优值,那么我们可以考虑
1)包含 nums[n] 的最优值,这时可以考虑和 n-2 的全局最优相加
2)不包含 nums[n],也即 n-1 处的全局最优
那么我们的状态转移方程就可以写成这样啦
d p [ n ] = m a x ( d p [ n − 1 ] , n u m s [ n ] + d p [ n − 2 ] ) \bm{dp[n]=max( dp[n-1], nums[n]+dp[n-2])} dp[n]=max(dp[n1],nums[n]+dp[n2])

代码

class Solution {
public:
    int rob(vector<int> &nums) {
        if (nums.empty())
            return 0;
        if (nums.size() == 1)
            return nums[0];
        if (nums.size() == 2 )
            return max(nums[0],nums[1]);
        vector<int> dp = {nums[0], max(nums[0], nums[1])};
        for (int n=2; i<nums.size(); n++) {
            dp.push_back( max(dp[n-1], dp[n-2] + nums[n]) );
        }          
        return dp.back();
    }
};

你可能感兴趣的:(LeetCode)