文章目录
0. 前言
相关:
1. LIS 变种+经典变种

本题很考思维抽象。
重点: 线性 dp、LIS 问题、思维抽象
思路:
- 状态定义:
f[i]表示所有以a[i]结尾的上升子序列和的最大值
- 状态转移:
- 分类依据:倒数第二个数是哪个数,可将状态分类为倒数第二个数为空、为
a[1]、a[2]、...、a[i-1],总共是有i种情况,假设倒数第二个数是a[k]的话:- 当
a[i] > a[k]时发生状态转移,有f[i] = max(f[i], f[k] + a[i]),k = 0, 1, 2,...,i-1
- 当
- 分类依据:倒数第二个数是哪个数,可将状态分类为倒数第二个数为空、为
- 状态转移方程:
f[i] = max(f[i], f[k] + a[i]),k = 0, 1, 2,...,i-1
就是把求 LIS 状态转移方程的 +1 操作变成了 +a[i],就行了。
就从状态定义、集合划分角度考虑问题就行了。也没必要太纠结像不像的。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e3+5;
int n;
int a[N];
int f[N];
int main() {
cin >> n;
for (int i = 0; i < n; ++i) cin >> a[i];
for (int i = 0; i < n; ++i) {
f[i] = a[i];
for (int j = 0; j < i; ++j)
if (a[i] > a[j])
f[i] = max(f[i], f[j] + a[i]);
}
int res = 0;
for (int i = 0; i < n; ++i) res = max(res, f[i]);
cout << res << endl;
return 0;
}
博客围绕LIS变种及经典变种问题展开,以1016. 最大上升子序列和为例,强调该题对思维抽象的考查。介绍了解题思路,包括状态定义和状态转移,从状态定义、集合划分角度考虑问题,还给出了状态转移方程。
373

被折叠的 条评论
为什么被折叠?



