【错题集-编程题】不相邻取数(动态规划 - 线性 dp)

简介: 【错题集-编程题】不相邻取数(动态规划 - 线性 dp)


一、分析题目

状态表示:

  • f[i]:从前 i 个数中挑选,最后一个位置的数必选,此时的最大和。
  • g[i]:从前 i 个数中挑选,最后一个位置的数不选,此时的最大和。

状态转移方程:

  • f[i] = g[i-1] + arr[i]
  • g[i] = max(f[i-1], g[i-1])

初始化:

  • f[0] = 0,g[0] = 0

二、代码

1、没看题解之前AC的代码

//一维dp-2个状态
#include <iostream>
using namespace std;
 
const int N = 2e5+10;
int a[N], f[N], g[N];
 
int main()
{
    int n;
    cin >> n;
    for(int i=1; i<=n; i++)
        cin >> a[i];
    for(int i=1; i<=n; i++)
    {
        f[i]=max(f[i-1], g[i-1]+a[i]);
        g[i]=max(f[i-1], g[i-1]);
    }
    cout << max(f[n], g[n]) << endl;
    return 0;
}
 
//一维dp-1个状态
#include <iostream>
using namespace std;
 
const int N = 2e5+10;
int a[N], dp[N];
 
int main()
{
    int n;
    cin >> n;
    for(int i=0; i<n; i++)
        cin >> a[i];
    dp[0]=a[0], dp[1]=max(a[0], a[1]);
    for(int i=2; i<n; i++)
        dp[i]=max(dp[i-2]+a[i], dp[i-1]);
    cout << dp[n-1] << endl;
    return 0;
}
 
//力扣AC代码
//一维dp-2个状态
class Solution {
public:
    int rob(vector<int>& nums) {
        int n=nums.size();
        vector<int> f(n+1);
        vector<int> g(n+1);
        for(int i=1; i<=n; i++)
        {
            f[i]=max(f[i-1], g[i-1]+nums[i-1]);
            g[i]=max(f[i-1], g[i-1]);
        }
        return max(f[n], g[n]);
    }
};
 
//一维dp-1个状态
public:
    int rob(vector<int>& nums) {
        int n=nums.size();
        if(n==1) return nums[0];
        vector<int> dp(n);
        dp[0]=nums[0], dp[1]=max(nums[0], nums[1]);
        for(int i=2; i<n; i++)
            dp[i]=max(dp[i-2]+nums[i], dp[i-1]);
        return dp[n-1];
    }
};

2、值得学习的代码

#include <iostream>
using namespace std;
 
const int N = 2e5 + 10;
 
int n;
int arr[N];
int f[N], g[N];
 
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> arr[i];
 
    for(int i = 1; i <= n; i++)
    {
        f[i] = g[i - 1] + arr[i];
        g[i] = max(f[i - 1], g[i - 1]);
    }
 
    cout << max(f[n], g[n]) << endl;
 
    return 0;
}

三、反思与改进

典型的 “打家劫舍” 系列问题,但我还是没能直接 AC,一直显示数组越界,我找了半天的边界,寻思着也没错,后来再仔细看题,发现数据范围看错了,晕这是什么低级错误!


相关文章
|
SQL NoSQL Linux
『GitHub项目圈选11』推荐5款本周 深受开发人员青睐 的开源项目
『GitHub项目圈选11』推荐5款本周 深受开发人员青睐 的开源项目
509 1
|
11月前
|
SQL 数据库连接 Linux
数据库编程:在PHP环境下使用SQL Server的方法。
看看你吧,就像一个调皮的小丑鱼在一片广阔的数据库海洋中游弋,一路上吞下大小数据如同海中的珍珠。不管有多少难关,只要记住这个流程,剩下的就只是探索未知的乐趣,沉浸在这个充满挑战的数据库海洋中。
318 16
|
10月前
|
Java 开发者 UED
Java 输入处理的常见错误
本文深入探讨了Java中输入处理的常见错误与认知偏差,重点分析了`Scanner`类的使用误区。例如,`nextInt()`后紧跟`nextLine()`会因残留换行符导致输入跳过,需额外调用`nextLine()`清理缓冲区;`nextLine()`始终返回字符串,需手动转换数据类型;处理多数字输入时,应结合`split()`与`Integer.parseInt()`方法。通过剖析这些问题,帮助开发者理解`Scanner`的工作机制,提升输入处理代码的健壮性与准确性。
317 3
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
303 2
|
C++ 容器
【C++】Vector -- 详解(下)
【C++】Vector -- 详解(下)
|
存储 前端开发 Java
JavaWeb基础7——会话技术Cookie&Session
会话技术、Cookie的发送和获取、存活时间、Session钝化与活化、销毁、用户登录注册“记住我”和“验证码”案例
JavaWeb基础7——会话技术Cookie&Session
|
SQL 缓存 运维
使用篇丨链路追踪(Tracing)很简单:链路实时分析、监控与告警
使用篇丨链路追踪(Tracing)很简单:链路实时分析、监控与告警
6858 86
使用篇丨链路追踪(Tracing)很简单:链路实时分析、监控与告警
|
JavaScript 前端开发 关系型数据库
Node.js 连接 MySQL
Node.js 连接 MySQL
274 5
|
监控 安全 网络安全
|
存储 前端开发 JavaScript
什么是web与搭建自己的第一个pikachu靶场
本文是关于Web基础知识和搭建Pikachu靶场的教程。首先介绍了Web的定义,强调其作为互联网信息传输方式的核心是超链接,以及HTML、CSS和JavaScript在构建网页中的作用。接着,详细讲解了如何在本地使用phpStudy搭建Pikachu靶场,包括下载相关软件、配置安装路径、启动环境和初始化数据库设置。对于使用特定Win7系统的用户,提供了因系统自带phpStudy导致安装问题的解决办法。分享了学习心得和每日一言,鼓励专注力的重要性。