动态规划之抢劫问题-LT213
找到大问题和小问题之间共有的特性,列出一定的状态转移规律,然后设计满足条件的小问题解决方案,最后凭借记忆中的中间值快速求出最终解
动态规划问题的复杂性在于你永远不知道下一个题目中的状态是什么,有什么样的状态转移规律,抢劫房子的问题是一个经典的动态规划问题,是裴波那切数列问题的一种,类似于爬楼梯。。。它分为单向抢劫与环形抢劫
单向抢劫
单项抢劫的题目描述为:抢劫一排住户,但是不能抢邻近的住户,求最大抢劫量。
单向的抢劫问题还是比较简单的,我们可以定义一个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的更多相关文章
- 转载:hdu 动态规划题集
		
1.Robberies 连接 :http://acm.hdu.edu.cn/showproblem.php?pid=2955 背包;第一次做的时候把概率当做背包(放大100000倍化为整数): ...
 - leetcode:House Robber(动态规划dp1)
		
You are a professional robber planning to rob houses along a street. Each house has a certain amount ...
 - 百度之星资格赛 hdu 4826 Labyrinth 动态规划
		
/********************* Problem Description 是一仅仅喜欢探险的熊.一次偶然落进了一个m*n矩阵的迷宫,该迷宫仅仅能从矩阵左上角第一个方格開始走,仅仅有走到右上 ...
 - leetcode算法刷题(二)——动态规划(一)
		
上次刷了五六道题,都是关于string处理的,这次想换个知识点刷一下,然后再回头刷string的题,当做复习.. 这几天主要会选择动态规划的题目,因为以前从没刷过这方面的东西,很多东西都不是很懂..就 ...
 - hdu 动态规划(46道题目)倾情奉献~ 【只提供思路与状态转移方程】(转)
		
HDU 动态规划(46道题目)倾情奉献~ [只提供思路与状态转移方程] Robberies http://acm.hdu.edu.cn/showproblem.php?pid=2955 背包 ...
 - 【转载】 HDU 动态规划46题【只提供思路与状态转移方程】
		
1.Robberies 连接 :http://acm.hdu.edu.cn/showproblem.php?pid=2955 背包;第一次做的时候把概率当做背包(放大100000倍化为整数) ...
 - 动态规划(DP)算法
		
参考https://blog.csdn.net/libosbo/article/details/80038549 动态规划是求解决策过程最优化的数学方法.利用各个阶段之间的关系,逐个求解,最终求得全局 ...
 - 动态规划:HDU-2955-0-1背包问题:Robberies
		
解题心得: 这题涉及概率问题,所以要运用概率的知识进行解答.题目要求不被抓到的概率,但是给出的是被抓到的概率,所要用1减去后得到答案.最好使用double类型,避免精度问题导致WA. 先算出可以抢劫的 ...
 - 【JAVA算法题】职业抢劫
		
题目 /*You are a professional robber planning to rob houses along a street. * Each house has a certain ...
 
随机推荐
- [kuangbin带你飞]专题九 连通图E  POJ 3177	Redundant Paths
			
这个题最开始我想的是,直接缩点求双连通分量,连接这些双联通分量不就行了吗? 但是其实是不对的,双连通内部双联通,我们如果任意的连接一条边在这些双联通分量之间,他们之间有没有桥其实并不知道. 我应该是求 ...
 - [转][ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [上篇]
			
微软在千禧年推出 .NET战略,并在两年后推出第一个版本的.NET Framework和IDE(Visual Studio.NET 2002,后来改名为Visual Studio),如果你是一个资深的 ...
 - [C++] WinAES的问题
			
WinAES是个不错的windows CAPI封装. 如果C++程序需要和java的程序进行aes加解密通讯,那么WinAES的代码是有问题的. java的aes代码缺省不会设置IV而且采用ECB模式 ...
 - 【u238】暴力摩托
			
Time Limit: 1 second Memory Limit: 64 MB [问题描述] 晚会上大家在玩一款"暴力摩托"的游戏,它拥有非常逼真的画面和音响效果! 当然了,车子 ...
 - React 简书
			
create-react-app jianshu yarn add styled-components -D 利用js写css样式 样式会更高效 https://github.com ...
 - 【js】vue 2.5.1 源码学习 (十) $mount 挂载函数的实现
			
大体思路(九) 本节内容: 1. $mount 挂载函数的实现. // 将Vue.prototype.$mount 缓存下来 ==>mountComponet(this,el) { // 组建挂 ...
 - Argus--[优先队列]
			
Description A data stream is a real-time, continuous, ordered sequence of items. Some examples inclu ...
 - LOGO的浮空显示-Verilog
			
为了方便生成准确的mif数据,以实现特定的透明效果.使用Photoshop将网上下载的Logo修改颜色,保存大小为120*120像素,如图1所示. 图1 ps修改后的Logo 使用Pic2mif软件, ...
 - Array数组的常用方法
			
1.concat()链接数组 var a = [1,2,3]; console.log(a.concat(4,5));//[1,2,3,4,5] 2.join()分隔符链接数组变字符串,如果省略该参数 ...
 - Java 趣事之 a=a++ 和 a=++a(转)
			
转自:https://blog.csdn.net/LovePluto/article/details/81062176 如果问 a++ 和 ++a 的区别,估计很多都能回答上来.a++ 是先取 a 的 ...