简单动态规划-LeetCode198

  • 题目:House Robber

You are 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.

  • 去掉背景题目大意是:给出一串无序整数序列A,要求找出子序列B,要求B不得去A中相邻的元素,是的B的和最大。

如:A={3,1,1,8}最大子序列和为11,B={3,8}

  • 一个简单的动态规划问题,递归方程如下:

定义d[i]表示取序列A前i个数的最大子序列和,A[i]表示序列A的第i个元素

基本想法:因为题目要求不能取相邻元素,那么假设取了元素A[i-1]那么就无法取元素A[i],所以当遍历到元素A[i]时,假设d[i-2]加上A[i-1]大还是加上A[i]大。

  • 代码如下:
 1 public class Solution {
 2     public int rob(int[] nums) {
 3         if (nums.length == 0)
 4             return 0;
 5         int[] d = new int[nums.length + 1];
 6         d[0] = 0;
 7         d[1] = nums[0];
 8         for (int i = 1; i < nums.length; ++i) {
 9             d[i + 1] = (d[i] >= d[i - 1] + nums[i]) ? d[i]
10                     : (d[i - 1] + nums[i]);
11         }
12         return d[nums.length];
13     }
14 }

这是我刚开始提交的代码,后来看了题目讨论区,也发现自己用一个数组将所有过程值保留时没必要的,只需要保留前面两个的子问题值即可,优化:

 1 public class Solution {
 2     public int rob(int[] nums) {
 3         int pre_2 = 0;
 4         int pre = 0;
 5         for (int i = 0; i < nums.length; ++i) {
 6             int tmp = pre;
 7             pre = Math.max(pre, pre_2+nums[i]);
 8             pre_2 = tmp;
 9         }
10         return pre;
11     }
12 }

为了去掉数组为空时的判断,特意将子问题向前推了一个。

时间: 2024-10-11 09:26:52

简单动态规划-LeetCode198的相关文章

HDUOJ----2571(命运)(简单动态规划)

命运 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8600    Accepted Submission(s): 3032 Problem Description 穿过幽谷意味着离大魔王lemon已经无限接近了! 可谁能想到,yifenfei在斩杀了一些虾兵蟹将后,却再次面临命运大迷宫的考验,这是魔王lemon设下的又一个机关.要知

简单动态规划问题分析

例题: 1022: 菜鸟和大牛(csuoj) 像这一类问题,首先不管是属于什么类型的,如果是按照题目的思路一步步走下来,然后运行,最后肯定是要超时的,究其原因,它的时间复杂度很不合理,最后是呈现指数增长的方式的.ACM本来就是研究最优算法的,所以不管结果如何,这个方法绝对不是优先选择的. 然后通过由下向上进行分析求解,会发现虽然思考问题的方式改变并不大,但是最后的大部分结果在还没有进行大量的运算之前就被我们排除了.这个方法的名字并不重要,重要的是以后解题时这种方法都应该是自己优先考虑的. 简单动

hdu 1003 Max Sum 简单动态规划

很简单的动态规划但ac率低于四分之一了,状态转移方程: dp[i]=max(dp[i-1]+a[i],a[i]) 注意几点: case 之间有空格 输入的最小负数为-1000 有多组答案找出第一个的意思是,从头便利,得到第一个最大的和就输出被,然后break: /************************************************************************* > File Name: hdu1231.cpp > Author: yang >

51nod 1270 数组的最大代价 思路:简单动态规划

这题是看起来很复杂,但是换个思路就简单了的题目. 首先每个点要么取b[i],要么取1,因为取中间值毫无意义,不能增加最大代价S. 用一个二维数组做动态规划就很简单了. dp[i][0]表示第i个点取1时(第0-i个点)得到的最大代价之和. dp[i][1]表示第i个点取b[i]时(第0-i个点)得到的最大代价之和. 每一个都由前面两个推出. #include <bits\stdc++.h> using namespace std; int a[50005]; int dp[50005][2];

HDU 1176 免费馅饼 简单动态规划

世道很简单的动态规划,但是却错了,让我很无语,改来改去还是不对,第二天有写就对了,之后我就耐着性子慢慢比较之前的错误代码,发现 第一次错:纯粹用了a[i][j]+=max3(a[i+1][j-1], a[i+1][j], a[i+1][j+1]);没有考虑j为0没有a[i+1][j-1]的存在和j为10时没有a[i+1][j+1]的存在 第二次错:我纠正了第一次的错误,把j为0和10单独考虑,这是数塔类型,我是自下向上推得,所以行数应该从最大的时间m=t:m-1开始的,但我写的是m,我感觉应该没

简单动态规划

初次接触到ACM,发现有很多的问题都不会 认识到了难度,自己还是蒟蒻(巨弱)啊 这次学到的是一道区域型的动态规划问题吧,虽然对很多人来说很简单 一开都没啥思路就会画个图 后面看了题解才知道要用到动态规划,可是还是不会啊 然后去了解了下,啥叫动态规划问题 动态规划程序设计是对解最优化问题的一种途径.一种方法,而不是一种特殊算法.不像搜索或数值计算那样,具有一个标准的数学表达式和明确清晰的解题方法. 动态规划程序设计往往是针对一种最优化问题,由于各种问题的性质不同,确定最优解的条件也互不相同,因而动

简单动态规划---动态的数字三角形

动态的数字三角形 难度级别:B: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 一个数字组成的三角形,有n行,第i行有i个数.从第一个数开始,每次可以往左下或右下走一格,直到走到最后一行,把沿途经过的数全部加起来.如何走才能得到最大的和?    举个例子:                           为了简单起见,输入时将每行的数依次输入,第一个数之前并不输入空格. 输入 第一行:n,表示这个三角形共有n行第二至n+1行:依次为这

HDU 2041 超级楼梯 简单动态规划

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2041题目大意:有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?这道题目在之前的随笔--动态规划入门之小明课间爬台阶--中有详细地讲解过,和之前地随笔地不同之处在于这里你只能跨一步或两部,而之前的随笔中小明还可以一下子跨三布.所以,这里推导出地状态转移方程为:        当n=0或1时,f[n] = 1        当n>=2时,f[n] = f[n-

HDU 1028 简单动态规划

"Well, it seems the first problem is too easy. I will let you know how foolish you are later." feng5166 says. "The second problem is, given an positive integer N, we define an equation like this: N=a[1]+a[2]+a[3]+...+a[m]; a[i]>0,1<=m