找到大问题和小问题之间共有的特性,列出一定的状态转移规律,然后设计满足条件的小问题解决方案,最后凭借记忆中的中间值快速求出最终解

动态规划问题的复杂性在于你永远不知道下一个题目中的状态是什么,有什么样的状态转移规律,抢劫房子的问题是一个经典的动态规划问题,是裴波那切数列问题的一种,类似于爬楼梯。。。它分为单向抢劫与环形抢劫

单向抢劫

单项抢劫的题目描述为:抢劫一排住户,但是不能抢邻近的住户,求最大抢劫量。

单向的抢劫问题还是比较简单的,我们可以定义一个dp数组,记录抢劫位置为i处时候的最大抢劫数目,代码如下:

    private int[] dp;

    private int rob(int[] nums){
if(nums.length == 0) return 0;
if(nums.length == 1) return nums[0];
dp = new int[nums.length + 1];
Arrays.fill(dp, -1);
dp[0] = 0;
return helper(nums, nums.length);
} private int helper(int[] nums, int n){
if(n < 0) return 0;
if(dp[n] != -1) return dp[n];
dp[n] = Math.max(helper(nums, n - 1), helper(nums, n - 2) + nums[n-1]);
return dp[n];
}

这样的做法是没问题,而且符合动态规划问题的一般思路,但是还有可以优化的地方,我们这样的解法的空间复杂度较高,通过分析题目我们可以知道dp[i]仅与前两个状态有关系,所以我们可以采取如下的方式边记边忘,这样就可以成功的把空间复杂度降低为O(1)

public int rob(int[] nums) {
int pre2 = 0, pre1 = 0;
for (int i = 0; i < nums.length; i++) {
int cur = Math.max(pre2 + nums[i], pre1);
pre2 = pre1;
pre1 = cur;
}
return pre1;
}

环形抢劫

环形抢劫又变了!第一个房子和最后一个房子成了邻居,所以我们就不可以同时把他们两家一块儿抢了了,但是细细一想,既然不能同时抢劫,那么把它分成0到numSize-2和1到numSize-1不久可以了吗,保证了他们不当邻居,然后求出两者的最大值,这样我们就可以继续用单向的思路去把它解决了!

    private int robII(int[] nums){
if(nums==null||nums.length==0)
return 0;
int n=nums.length;
if(n==1)
return nums[0];
return Math.max(helper(0,n-2,nums),helper(1,n-1,nums));
}
private int helper(int start, int end, int[] nums){
int[]dp=new int[end-start+2];
dp[0]=0;
dp[1]=nums[start];
for(int i=2;i<=(end-start+1);i++){
dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i-1+start]);
}
return dp[end-start+1];
}

动态规划之抢劫问题-LT213的更多相关文章

  1. 转载:hdu 动态规划题集

    1.Robberies 连接 :http://acm.hdu.edu.cn/showproblem.php?pid=2955     背包;第一次做的时候把概率当做背包(放大100000倍化为整数): ...

  2. leetcode:House Robber(动态规划dp1)

    You are a professional robber planning to rob houses along a street. Each house has a certain amount ...

  3. 百度之星资格赛 hdu 4826 Labyrinth 动态规划

    /********************* Problem Description 是一仅仅喜欢探险的熊.一次偶然落进了一个m*n矩阵的迷宫,该迷宫仅仅能从矩阵左上角第一个方格開始走,仅仅有走到右上 ...

  4. leetcode算法刷题(二)——动态规划(一)

    上次刷了五六道题,都是关于string处理的,这次想换个知识点刷一下,然后再回头刷string的题,当做复习.. 这几天主要会选择动态规划的题目,因为以前从没刷过这方面的东西,很多东西都不是很懂..就 ...

  5. hdu 动态规划(46道题目)倾情奉献~ 【只提供思路与状态转移方程】(转)

    HDU 动态规划(46道题目)倾情奉献~ [只提供思路与状态转移方程] Robberies http://acm.hdu.edu.cn/showproblem.php?pid=2955      背包 ...

  6. 【转载】 HDU 动态规划46题【只提供思路与状态转移方程】

    1.Robberies 连接 :http://acm.hdu.edu.cn/showproblem.php?pid=2955      背包;第一次做的时候把概率当做背包(放大100000倍化为整数) ...

  7. 动态规划(DP)算法

    参考https://blog.csdn.net/libosbo/article/details/80038549 动态规划是求解决策过程最优化的数学方法.利用各个阶段之间的关系,逐个求解,最终求得全局 ...

  8. 动态规划:HDU-2955-0-1背包问题:Robberies

    解题心得: 这题涉及概率问题,所以要运用概率的知识进行解答.题目要求不被抓到的概率,但是给出的是被抓到的概率,所要用1减去后得到答案.最好使用double类型,避免精度问题导致WA. 先算出可以抢劫的 ...

  9. 【JAVA算法题】职业抢劫

    题目 /*You are a professional robber planning to rob houses along a street. * Each house has a certain ...

随机推荐

  1. 神经网络入门——7or 感知器

    OR 感知器 OR 感知器与 AND 感知器很类似,在下图中,OR 感知器与 AND 感知器有相同的分割线,只是 OR 感知器分割线下移了一段距离.对权重或者偏置做怎样的设置可以实现这个效果?用下面的 ...

  2. win10 uwp 在 Canvas 放一个超过大小的元素会不会被裁剪

    我尝试在一个宽度200高度200的 Canvas 放了一个宽度 300 高度 300 的元素,这个元素会不会被 Canvas 裁剪了? 经过我的测试,发现默认是不会被裁剪 火火问了我一个问题,如果有一 ...

  3. Vue 获取DOM元素ref

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. .net连接数据库

    /* 连接数据库步骤-- 1.创建连接字符串 data source = ... 计算机名称 initial catalog = ... 数据库名称 integrated security = tru ...

  5. P1060 梦中的统计

    题目描述 Bessie 处于半梦半醒的状态.过了一会儿,她意识到她在数数,不能入睡. Bessie的大脑反应灵敏,仿佛真实地看到了她数过的一个又一个数.她开始注意每一个数码(0..9):每一个数码在计 ...

  6. jieba—parallel

    jieba 并行处理进行测试,注意:并行分词仅支持默认分词器 jieba.dt 和 jieba.posseg.dt import sys import time import jieba jieba. ...

  7. testng+ant+jenkins持续集成UI自动化

    一.环境搭建 1. 安装testNG插件到eclipse. -) 选择菜单 Help /Software updates / Find and Install. -) 点击add button然后在l ...

  8. linux I/O 内存分配和映射

    I/O 内存区必须在使用前分配. 分配内存区的接口是( 在 <linux/ioport.h> 定义): struct resource *request_mem_region(unsign ...

  9. 【37.48%】【hdu 2587】How far away ?(3篇文章,3种做法,LCA之树上倍增)

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  10. MFC下获取系统内存和当前进程的内存使用情况

    GlobalMemoryStatusEx来获取系统的内存使用情况 GetProcessMemoryInfo获取某个进程的内存使用情况.和任务管理器看到的是一样的. 具体代码如下: void GetSy ...