leetcode 198 打家劫舍(动态规划)

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
示例 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 。
思考:
n个房屋,每个房间都有盗取/不盗取两种可能,类似求子集(暴力搜索)的方式,在不触发警报的情况下,选择总和最大的子集,最多有2^n种可能,时间复杂度为O(n)
贪心算法是否可行?
例如:在满足不触发警报的同时,每次选择财宝最多的房间
若考虑动态规划(dp)方法,如何确认dp原问题与子问题、状态、边界条件、状态转移方程?
由于同时从相邻的两个房屋中盗取财宝就会触发报警器,故:
a、若选择第i个房间盗取财宝,就一定不能选择第i-1个房间盗取财宝
b、若不选择第i个房间盗取财宝,则相当于只考虑前i-1个房间盗取财宝
算法思路:
1、确认原问题与子问题:
原问题为求n个房间的最优解,子问题为求前1个房间,前2个房间,……,前n个房间的最优解
2、确认状态:
第i个状态即为前i个房间能够获得的最大财宝
3、确认边界条件的值:
前1个房间的最优解,第1个房间的财宝
前2个房间的最优解,第1、2个房间的财宝
4、确定状态转移方程:
a、选择第i个房间:第i个房间 + 前i-2个房间的最优解
b、不选择第i个房间:前i-1个房间的最优解
动态规划转移方程:
dp[i] = max(dp[i-1], dp[i-2] + nums[i]);(i >= 3)

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 0){
            return 0;
        }
        if (nums.size() == 1){
            return nums[0];
        }
        vector<int> dp(nums.size(), 0);    //设第i个房间的最优解为dp[i]
        dp[0] = nums[0];
        dp[1] = max(nums[0], nums[1]);
        for (int i = 2; i < nums.size(); i++){
            dp[i] = max(dp[i-1], dp[i-2]+nums[i]);
        }
        return dp[nums.size()-1];
    }
};
发布了65 篇原创文章 · 获赞 4 · 访问量 981

猜你喜欢

转载自blog.csdn.net/CLZHIT/article/details/103977091
今日推荐