ToB企服应用市场:ToB评测及商务社交产业平台

标题: 线性dp:大盗阿福(打家劫舍) [打印本页]

作者: 曂沅仴駦    时间: 2024-8-24 08:02
标题: 线性dp:大盗阿福(打家劫舍)
大盗阿福

力扣题目链接)
题目叙述:

阿福是一名经验丰富的大盗。趁着月黑风高,阿福计划今晚洗劫一条街上的店铺。这条街上一共有N家店铺,每家店中都有一些现金。阿福事先观察得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警员就会蜂拥而至。作为一向审慎作案的大盗阿福不愿意冒着被警员追捕的风险行窃。他想知道,在不惊动警员的情况下,他今晚最多可以得到多少现金?
输入格式

输出格式

输入样例:
  1. 2
  2. 3
  3. 1 8 2
  4. 4
  5. 10 7 6 14
复制代码
输出样例:
  1. 8
  2. 24
复制代码
样例解释:

动态规划思路分析

状态变量以及它的含义

递推公式


  • 我们设dp ,在i的这个位置有两种状态:

    • 1.第i家店铺不偷——dp=dp[i-1]
    • 2.第i家店铺偷——dp=dp[i-2]+w,w为第i家店铺的价值

详细细节如下图所示:


遍历顺序:


  • 由上面两步分析可知,dp的状态一定是由前面dp[i-1],dp[i-2],推出来的,所以说遍历顺序一定是从前向后遍历。
如何初始化?


  • 我们首先得处理好边界条件:dp[0]和dp[1]怎么处理?
  • 偷前0家店铺的最大价值显然是0,偷前1家店铺的最大价值显然为w[1]
  • 处理好边界条件以后,我们再从前向后,依据递推公式进行递推就行了
举例验证dp数组

下标:1,2,3,4
w:10,7,6,14
dp:10,10,16,24

  • 通过样例2分析可知,我们的dp数组没有分析错。因此我们验证了我们的dp数组的正确性。
优化


  • 我们可以用dp[i-1]的状态直接推出dp的状态。
  • 我们状态表示可以优化成:

    • f[0]表示不偷第i家店铺能获取的最大值
    • f[1]表示偷第i家店铺能获取的最大值

  • 那么我们的状态转移方程就可以从dp[i-1]推出,不偷第i家店铺,那么我们就可以偷第i-1家店铺,也可以不偷,我们选取这两个之中的最大值,假如偷第i家店铺的话,第i-1家店铺我们一定只能选择不偷。

    • 不偷:dp[0]=max(dp[i-1][0],dp[i-1][1])
    • 偷:dp[1]=dp[i-1][0]+w


优化后的边界处理:


  • 不偷第1家店铺:f[0]=0
  • 偷第1家店铺:f[1]=w[1]
优化后的代码处理:

[code]scanf("%d",&t)    while(t--){        scanf("%d",&n);        for(int i=1;i




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4