这是一个经典的动态规划 (Dynamic Programming) 问题,通常被称为最大不相邻子序列和房屋偷盗问题 (House Robber Problem) 的变体。

动态规划解法

我们可以定义一个动态规划数组 ,其中 表示考虑数组的前 个元素时,能得到的最大不相邻元素之和。

对于数组中的第 个元素 (数组从 开始索引),我们有两种选择:

  1. 选择 (取) 如果我们选择 ,那么我们不能选择前一个元素 。此时,最大和是 加上考虑前 个元素时的最大和,即
  2. 不选择 (不取) 如果我们不选择 ,那么最大和就是考虑前 个元素时的最大和,即

因此,状态转移方程为:

初始状态 (Base Cases)

  • (空数组):
  • (只有一个元素 ):
  • (有两个元素 ): 只能取一个,所以 。根据状态转移方程:

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<ll> dp(n);
    ll ans = 0;

    for (int i = 0; i < n; i++) {
        int a;
        cin >> a;

        // 取a
        ll t1 = (i > 1 ? dp[i - 2] : 0) + a;
        // 不取a
        ll t2 = (i > 0 ? dp[i - 1] : 0);
        dp[i] = max(t1, t2);
        ans = max(ans, dp[i]);
    }

    cout << ans << endl;
}