这是一个经典的动态规划 (Dynamic Programming) 问题,通常被称为最大不相邻子序列和或房屋偷盗问题 (House Robber Problem) 的变体。
动态规划解法
我们可以定义一个动态规划数组 ,其中
表示考虑数组的前
个元素时,能得到的最大不相邻元素之和。
对于数组中的第 个元素
(数组从
开始索引),我们有两种选择:
- 选择 (取)
: 如果我们选择
,那么我们不能选择前一个元素
。此时,最大和是
加上考虑前
个元素时的最大和,即
。
- 不选择 (不取)
: 如果我们不选择
,那么最大和就是考虑前
个元素时的最大和,即
。
因此,状态转移方程为:
初始状态 (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;
}

京公网安备 11010502036488号