【错题集-编程题】不相邻取数(动态规划 - 线性 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,一直显示数组越界,我找了半天的边界,寻思着也没错,后来再仔细看题,发现数据范围看错了,晕这是什么低级错误!


相关文章
|
1月前
|
算法 测试技术 C++
【动态规划】【前缀和】【数学】2338. 统计理想数组的数目
【动态规划】【前缀和】【数学】2338. 统计理想数组的数目
|
1月前
|
算法 测试技术 C++
【动态规划】【矩阵快速幂】【滚动向量】C++算法552. 学生出勤记录 II
【动态规划】【矩阵快速幂】【滚动向量】C++算法552. 学生出勤记录 II
|
1月前
【每日一题Day146】给定行和列的和求可行矩阵 | 贪心
【每日一题Day146】给定行和列的和求可行矩阵 | 贪心
27 0
|
1月前
|
算法 测试技术 C++
【动态规划 状态机dp 性能优化】3098. 求出所有子序列的能量和
【动态规划 状态机dp 性能优化】3098. 求出所有子序列的能量和
【动态规划 状态机dp 性能优化】3098. 求出所有子序列的能量和
|
1月前
【编程题-错题集】连续子数组最大和(动态规划 - 线性 dp)
【编程题-错题集】连续子数组最大和(动态规划 - 线性 dp)
|
1月前
【错题集-编程题】删除相邻数字的最大分数(动态规划 - 线性 dp)
【错题集-编程题】删除相邻数字的最大分数(动态规划 - 线性 dp)
|
1月前
|
存储
【错题集-编程题】合唱团(动态规划 - 线性 dp)
【错题集-编程题】合唱团(动态规划 - 线性 dp)
|
1月前
【编程题-错题集】分割等和子集(动态规划 - 01背包)
【编程题-错题集】分割等和子集(动态规划 - 01背包)
|
1月前
|
Shell 网络安全
【错题集-编程题】mari和shiny(动态规划-多源状态线性 dp)
【错题集-编程题】mari和shiny(动态规划-多源状态线性 dp)
|
10月前
|
算法 Android开发
LeetCode 周赛上分之旅 #41 结合离散化的线性 DP 问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
52 0