线性dp:大盗阿福(打家劫舍)
大盗阿福
- 本题与leetcode198题——打家劫舍的题意一模一样,阅读完本文以后可以尝试以下题目
题目叙述:
阿福是一名经验丰富的大盗。趁着月黑风高,阿福打算今晚洗劫一条街上的店铺。这条街上一共有N家店铺,每家店中都有一些现金。阿福事先调查得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警察就会蜂拥而至。作为一向谨慎作案的大盗阿福不愿意冒着被警察追捕的风险行窃。他想知道,在不惊动警察的情况下,他今晚最多可以得到多少现金?
输入格式
- 输入的第一行是一个整数T,表示一共有T组数据。
- 接下来的每组数据,第一行是一个整数N,表示一有N家店铺。
- 第二行是N个被空格分开的正整数,表示每一家店铺中的现金数量。每家店铺中的现金数量均不超过1000。
输出格式
- 对于每组数据,输出一行。该行包含一个整数,表示阿福在不惊动警察的情况下可以得到的现金数量。
输入样例:
2
3
1 8 2
4
10 7 6 14
输出样例:
8
24
样例解释:
- 对于第一组样例,阿福选择第2家店铺行窃,获得的现金数量为8。对于第二组样例,阿福选择第1和4家店铺行窃获得的现金数量为10+14=24.
动态规划思路分析
- 设我们打劫的店铺数量为
i,获取的价值和为dp,那么dp明显是i的一个函数,那么我们就用dp[i]作为状态变量,dp[i]表示偷前i家店铺所能获取的价值最大值
状态变量以及它的含义
- 由上面分析可知,我们设立
dp[i]作为状态变量,并且dp[i]的含义是偷前i家店铺所能获取收益的最大值.
递推公式
- 我们设
dp[i],在i的这个位置有两种状态:- 1.第i家店铺不偷——
dp[i]=dp[i-1] - 2.第i家店铺偷——
dp[i]=dp[i-2]+w[i],w[i]为第i家店铺的价值
- 1.第i家店铺不偷——
具体细节如下图所示:
遍历顺序:
- 由上面两步分析可知,
dp[i]的状态一定是由前面dp[i-1],dp[i-2],推出来的,所以说遍历顺序一定是从前向后遍历。
如何初始化?
- 我们首先得处理好边界条件:
dp[0]和dp[1]怎么处理? - 偷前0家店铺的最大价值显然是
0,偷前1家店铺的最大价值显然为w[1] - 处理好边界条件以后,我们再从前向后,依据递推公式进行递推就行了
举例验证dp数组
下标:1,2,3,4
w[i]:10,7,6,14
dp[i]:10,10,16,24
- 通过样例2分析可知,我们的dp数组没有分析错。因此我们验证了我们的dp数组的正确性。
优化
我们可以用
dp[i-1]的状态直接推出dp[i]的状态。我们状态表示可以优化成:
f[i][0]表示不偷第i家店铺能获取的最大值f[i][1]表示偷第i家店铺能获取的最大值
那么我们的状态转移方程就可以从
dp[i-1]推出,不偷第i家店铺,那么我们就可以偷第i-1家店铺,也可以不偷,我们选取这两个之中的最大值,如果偷第i家店铺的话,第i-1家店铺我们一定只能选择不偷。- 不偷:
dp[i][0]=max(dp[i-1][0],dp[i-1][1]) - 偷:
dp[i][1]=dp[i-1][0]+w[i]

- 不偷:
优化后的边界处理:
- 不偷第1家店铺:
f[i][0]=0 - 偷第1家店铺:
f[i][1]=w[1]
优化后的代码处理:
scanf("%d",&t)
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
f[1][0]=0;f[1][1]=w[1];
for(int i=2;i<=n;i++){
f[i][0]=max(f[i-1][0],f[i-1][1]);
f[i][1]=f[i-1][0]+w[i];
}
printf("%d\n",max(f[n][0],f[n][1]));
}
总结:

- 我们上面讲述的两种方法,第一种方法叫做分步转移,第二种方法叫做分类转移,在有些情况下,二者都能使用,而在某些题目当中,只能使用分类转移的方法,我们在以后也会介绍的!希望大家能理解这两种做法。
线性dp:大盗阿福(打家劫舍)的更多相关文章
- [OpenJudge8462][序列DP]大盗阿福
大盗阿福 总时间限制: 1000ms 内存限制: 65536kB [描述] 阿福是一名经验丰富的大盗.趁着月黑风高,阿福打算今晚洗劫一条街上的店铺. 这条街上一共有 N 家店铺,每家店中都有一些现金. ...
- LightOJ1044 Palindrome Partitioning(区间DP+线性DP)
问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...
- Codeforces 176B (线性DP+字符串)
题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...
- hdu1712 线性dp
//Accepted 400 KB 109 ms //dp线性 //dp[i][j]=max(dp[i-1][k]+a[i][j-k]) //在前i门课上花j天得到的最大分数,等于max(在前i-1门 ...
- 动态规划——线性dp
我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...
- POJ 2479-Maximum sum(线性dp)
Maximum sum Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 33918 Accepted: 10504 Des ...
- poj 1050 To the Max(线性dp)
题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...
- nyoj44 子串和 线性DP
线性DP经典题. dp[i]表示以i为结尾最大连续和,状态转移方程dp[i] = max (a[i] , dp[i - 1] + a[i]) AC代码: #include<cstdio> ...
- 『最大M子段和 线性DP』
最大M子段和(51nod 1052) Description N个整数组成的序列a[1],a[2],a[3],-,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M &g ...
- 『最长等差数列 线性DP』
最长等差数列(51nod 1055) Description N个不同的正整数,找出由这些数组成的最长的等差数列. 例如:1 3 5 6 8 9 10 12 13 14 等差子数列包括(仅包括两项的不 ...
随机推荐
- Jetpack Compose(7)——触摸反馈
目录 一.点按手势 1.1 Modifier.clickable 1.2 Modifier.combinedClickable 二.滚动手势 2.1 滚动修饰符 Modifier.verticalSc ...
- SpringBoot集成日志框架
springboot默认日志是打印在console中,不会保存在文件中.我们项目上线肯定要保存日志用于分析问题的. 使用xml配置日志保存 并不需要pom配置slf4j依赖,starter里面已经配置 ...
- yb课堂 订单列表开发,完结 《四十五》
Order.vue <template> <div class="main"> <!--订单列表--> <div class=" ...
- 通俗讲解promise
JavaScript 中的 Promise 是一种特殊的对象,它用于解决异步编程中的复杂性问题,特别是回调的问题.我们可以把它比喻成现实生活中的一个"承诺": 想象一下,你 ...
- 内部网关协议OSPF
开放最短路径优先OSPF,开放表明OSPF不受某一厂商控制,最短路径优先是因为使用了最短路径算法SPF. OSPF最主要的特征是使用链路状态协议,而不是RIP的距离向量路由协议.其余特点: ⑴使用洪泛 ...
- 有数大数据基础平台之智能运维平台EasyEagle介绍:集群队列篇
他来啦,他来啦!大数据基础平台发布会中提到的智能运维平台,他来啦! 作为数据平台的用户们,下述问题一直困扰着我们: 集群资源水位如何,利用率如何,是否需要扩容? 队列为什么最近大量任务出现pendin ...
- Day 5 - 双指针与折半搜索
双指针 本页面将简要介绍双指针. 引入 双指针是一种简单而又灵活的技巧和思想,单独使用可以轻松解决一些特定问题,和其他算法结合也能发挥多样的用处. 双指针顾名思义,就是同时使用两个指针,在序列.链表结 ...
- 2024-07-24:用go语言,给定一个整数数组 nums,其中至少包含两个元素。 可以根据以下规则执行操作:选择最前面两个元素删除、选择最后两个元素删除,或选择第一个和最后一个元素删除。 每次操作
2024-07-24:用go语言,给定一个整数数组 nums,其中至少包含两个元素. 可以根据以下规则执行操作:选择最前面两个元素删除.选择最后两个元素删除,或选择第一个和最后一个元素删除. 每次操作 ...
- 全网最适合入门的面向对象编程教程:27 类和对象的Python实现-Python中异常层级与自定义异常类的实现
全网最适合入门的面向对象编程教程:27 类和对象的 Python 实现-Python 中异常层级与自定义异常类的实现 摘要: 本文主要介绍了在使用 Python 进行面向对象编程时,异常的层级和如何使 ...
- oracle数据库状态查询
oracle数据库状态查询(表空间,表空间利用率,是否自动扩展,IOPS,MBPS,数据库总大小) 排除了('SYSAUX', 'USERS', 'SYSTEM','UNDOTBS1') 结果示例 - ...
