码迷,mamicode.com
首页 > 编程语言 > 详细

LeetCode之用C++写动态规划

时间:2020-03-14 13:17:06      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:strong   动态   影响   title   情况   为什么   数组   动态规划   方法   

Leetcode #198 打家劫舍

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

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


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

具体描述请查看Leetcode相关网页:https://leetcode-cn.com/problems/house-robber/

方法:动态规划(递推)

偷到第 n 家后会有 F(n) 的金额,其中 F(n) = max( F(n - 2), F(n - 3) ) + nums[n - 1] (因为不能偷相邻人家的钱)
那么为什么只要比较第 F(n - 2)F(n - 3) 就够了呢?不是还有 F(n - 4)、F(n - 5)..... 吗?
因为 F(n - 2) = max( F(n - 4), F(n - 5) ) + nums[n - 3] ; nums中存储的值必定大于等于0,所以 F(n - 2) >= max( F(n - 4), F(n - 5) ) ,同理
F(n - 3) >= max( F(n - 5), F(n - 6) );所以只要比较 F(n - 2)F(n - 3) 就可以了~
代码如下:


    //递推式: F(n) = max( F(n - 2), F(n - 3) ) + nums[n - 1];
    int rob(vector<int>& nums) {
        int n = nums.size();
        if(n == 0)  return 0;
        if(n == 1)  return nums[0];
        if(n == 2)  return max(nums[0], nums[1]);
        if(n == 3)  return max(nums[0] + nums[2], nums[1]);
        // 从F(4) = max( F( 2 ), F( 1 ) ) + nums[3];开始递推
        int ans, a = max(nums[0], nums[1]), b = nums[0],
            c = max(nums[0] + nums[2], nums[1]);// a 用来存F(n - 2), b用来存F(n - 3), c用来存F(n - 1)
        for(int i = 3;i < n;i++){
            ans = max(a, b) + nums[i];
            b = a;
            a = c;
            c = ans;
        }
        return max(ans, a);// 比较F(n)和F(n - 1),返回大的那个

LeetCode之用C++写动态规划

标签:strong   动态   影响   title   情况   为什么   数组   动态规划   方法   

原文地址:https://www.cnblogs.com/Codroc/p/12491445.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!