最长上升子序列
给定一个长度为 NN 的数列,求数值严格单调递增的子序列的长度最长是多少。
输入格式
第一行包含整数 NN。
第二行包含 NN 个整数,表示完整序列。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N≤10001≤N≤1000,
−109≤数列中的数≤109−109≤数列中的数≤109
输入样例:
7
3 1 2 1 8 5 6
输出样例:
4
关于动态规划,我们应该想一个问题,就是如何去规划步骤,我们思考,到如何走到这一步,和这一步的情况是什么样,这样说或许有些抽象。
我们看以下这个例子
例如:
3 1 2 1 8 5 6
按照题意,假设我们走到8
可能有以下几种情况。
{1,2,8}
{1,8}
{2,8}
那我们只需要最优子结构就好,也就是1,2,8这个情况。
那么我们是不是可以遍历 用dp[i]存储我们最优情况,那么我们要思考,没个最优子结构应该如何推导?
考虑dp[i]可以由哪些状态得到
//如果vec[i] < vec[j]
可以由前面的最大max(dp[j]+1,dp[i])得来。
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (vec[i] < vec[j]) {
vecdp[j] = max(vecdp[j], vecdp[i] + 1);
}
}
}
每次在满足vec[i] < vec[j]的情况下,做出两种转移,dp[前面]+1是最优解和此时已得到的是最优解推导而来。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 1e5;
vector<int> vec(N);
vector<int> vecdp(N);
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> vec[i];
}
vecdp.resize(n + 5);
fill(vecdp.begin(), vecdp.end(), 1);
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (vec[i] < vec[j]) {
vecdp[j] = max(vecdp[j], vecdp[i] + 1);
}
}
}
int ans = *max_element(vecdp.begin(), vecdp.begin() + n);
cout << ans;
return 0;
}
标签:vecdp,int,++,109,vec,序列,上升,最长,dp From: https://www.cnblogs.com/AnnaStore/p/18625219