一道简单的动态规划题目——House Robber

一、题目

House Robber(一道Leetcode上的关于动态规划的简单题目)具体描述如下:

There is a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have      security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.  Given a list of non-negative integers representing the amount of money of each        house, determine the maximum amount of money you can rob tonight without alerting the police.

二、题意理解:

1. 题目描述的意思是假设有一位专业的小偷要对街上一排互相相邻的房间实施偷盗,但没两个相邻的房间之间有安保措施,所以不能对两个相邻的房间同时实施偷盗,不然就会触发报警装置。给定一个数组列表,每个元素代表每间房子中的money的数目,题目要求在不触发警报的前提下,该小偷一次最多能偷多少money?

2. 这是一道典型的动态规划类型的题目,小偷在一次偷盗过程中有多种实施方案,每个方案的结果(偷得的money数目)不一定一样,目的就是要求出能得到最大数目的方案。假设给定的数组列表如下:

可以看到总共有10间房子,并且其中每间房子的money数量用黑色字体的数字标示。

  3. 算法思路:

      3.1 假设小偷偷得顺序是按照从左往右,那么最终停止的位置只能是9或10

      3.2 如果从位置10往前回溯,分别有两个可以选择的房子7和8,位置9也是一样的

      3.3 需要选择从左边开始到money数目最大的那个房子,那么可以看到这是一个递归的过程

3.4 因为中间会有一些重复的计算,比如在求位置10的向前回溯的时候,需要计算位置7的money值,计算位置9前溯同样需要计算位置7的money,所以我们需要将已经计算过的值进行记录

三、程序实例  

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Solution
{
public:
    int rob(vector<int>& nums)
     {
      int len = nums.size();
      maxRob.resize(len, -1);
      int m1 = robRec(nums, len-1);
      int m2 = robRec(nums, len-2);
     return m1 > m2?m1:m2;
}
   int robRec(vector<int>&nums, int pos)
     {
         if(pos < 0)
             return 0;
         if(maxRob[pos] >= 0)//判断是否已经计算过当前位置的值
            return maxRob[pos];
            int max1 = robRec(nums, pos-2);
            int max2 = robRec(nums, pos-3);
            maxRob[pos] =(max1 > max2?max1:max2) + nums[pos];
            return maxRob[pos];
}
private:
         vector<int> maxRob;
};

int main()
{
           int arr[] = {2,3,4,1,9 ,3 ,2, 3, 3 ,4};
            Solution so;
            vector<int> int_vec(arr, arr+sizeof(arr)/sizeof(int));
          cout << so.rob(int_vec);
           return 0;
}

    

时间: 2024-10-03 14:55:49

一道简单的动态规划题目——House Robber的相关文章

练习题(4) -- 一道简单而有有趣的题目

PS: 因为最近一会儿用C++ 写程序,一会儿是python, 一会儿又是java,搞得我都有点语法错乱了. 题目如下:一个字符串形如 "yazyypta"  从这个字符串中删除任何字符,得到的字符串都是它的子字符串,比如对于这个字符串 "ya", "ayy", "pta" 都是它的子字符串,所有的子字符串按照字母序比较大小,求最大的大小最大的子字符串 举几个例子 1) abc c 2)    bcbxa xa 3)   ba

一道简单题目的优化过程——抽签问题

题目来源:挑战程序设计竞赛 题目描述: 给定n个数字,选择四次,可以选择已经选择过的数字,问是否可以选出和为m的四个数. 首先,最基本的做法: 枚举四层,每一层枚举出一个数,求出所有四个数字不同的排列.时间复杂度为O(N^4). for (int i1=1;i1<=n;i++) for (int i2=i1;i2<=n;i2++) for (int i3=i2;i3<=n;i3++) for (int i4=i3;i4<=n;i4++) 让我们来一步步优化吧. 基本做法的本质是,枚

[SinGuLaRiTy] 动态规划题目复习

[SinGuLaRiTy-1026] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. [UVA 1025] A Spy in the Metro 题目描述 特工玛利亚被送到S市执行一个特别危险的任务.她需要利用地铁完成他的任务,S市的地铁只有一条线路运行,所以并不复杂. 玛利亚有一个任务,现在的时间为0,她要从第一个站出发,并在最后一站的间谍碰头.玛利亚知道有一个强大的组织正在追踪她,她知道如果一直呆在一个车站,她会有很大的被抓的风险,躲

从一道简单的dp题中学到的...

今天想学点动态规划的知识,于是就看了杭电的课件,数塔问题啊,LCS啊都是比较经典的动规了,然后随便看了看就开始做课后练习题... HDOJ 1421 搬寝室 http://acm.hdu.edu.cn/showproblem.php?pid=1421 题目大意:从n(n <= 2000)个数中选出k对数(即2*k个),使它们的差的平方和最小. 例如:从8,1,10,9,9中选出2对数,要使差的平方和最小,则应该选8和9.9和10,这样最小,结果为2 因为知道是dp的题,先建个dp[][]数组,然

动态规划题目

动态规划算法,在T大某位老师的书中说就是递推+重复子问题. 动态规划算法的效率主要与重复子问题的处理有关. 典型的题目有 陪审团,最大公共子串问题 1,最大公共子串问题 这个是动态规划的基础题目.动态规划就是递推和重复子结构. 确定了递推关系后.找到一个能极大地减少重复运算的子结构至关重要.选的好了,时间效率会很好. 这个问题,不妨设第一个串为a,长度为n,第二个串为b,长度m.那么最长的子序列长度为f(n,m) 当a[n]=a[m]时 f(n,m)=1+f(n-1,m-1) 否则f(n,m)=

一道简单的递推题(快速幂+矩阵乘法优化+滚动数组)

问题 F: 一道简单的递推题 时间限制: 1 Sec  内存限制: 128 MB提交: 546  解决: 48[提交][状态][讨论版] 题目描述 存在如下递推式: F(n+1)=A1*F(n)+A2*F(n-1)+...+An*F(1) 求第K项的值对1000000007取模的结果 输入 单组测试数据 第一行输入两个整数 n , k (1<=n<=100,n<k<=10000000000) 第二行输入 n 个整数 F(1)   F(2)   ...   F(n) 第三行输入 n

北方多校 又是一道简单题

又是一道简单题 12000ms 65536K 给出一棵有根树,每次查询给出两个节点 u 和 v,假设节点 f 是u,v的最近公共祖先,请查询以 f 为根的子树中,不在 u 到 v 这条链上且标号最小的节点. 输入格式 第一行输入正整数 T(T <= 30),表示共有T组输入数据. 对于每组数据,第一行输入两个正整数 n,m(n <= 50000,m <= 50000),表示节点数和询问数,节点编号 1 到 n,其中 1 是根节点. 接下来 n - 1 行,每行输入两个正整数u,v,表示标

poj 动态规划题目列表及总结

此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276,1322, 1414, 1456, 1458, 1609, 1644, 1664, 1690, 1699, 1740(博弈),1742, 1887, 1926(马尔科夫矩阵,求平衡), 1936, 1952, 1953, 1958, 1959, 1962, 1975,

动态规划题目(三)——最大连续乘积子串

动态规划题目(三)--最大连续乘积子串 1. 题目描述 给一个浮点数序列,取最大乘积连续子串的值,例如 -2.5,4,0,3,0.5,8,-1,则取出的最大乘积连续子串为3,0.5,8.也就是说,上述数组中,3 0.5 8这3个数的乘积30.58=12是最大的,而且是连续的. 2. 动态规划求解 动态规划求解题目的时候最重要的是要找到状态转移方程! 针对这道题目,我们使用两个变量记录当前最大值maxEnd, 和当前最小值minEnd.为什么记录当前最小值呢?因为数组中会出现负数,乘以一个负数的话