Acwing 最长上升子序列
题目
给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。
输入格式
第一行包含整数 N。
第二行包含 N 个整数,表示完整序列。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N≤1000
−10^9≤数列中的数≤ 10^9
输入样例:
7
3 1 2 1 8 5 6
输出样例:
4
题解
本题是非常经典的一道动态规划问题
首先进行状态分析
f[i]
代表以第i项为结尾的最长的连续递增子序列的长度
状态特征是最大值
从第1项开始递推,第i项的最长子序列长度应该为前i-1项中的某一项
长度+1,而寻找到这项的条件是g[i]>g[某项]
然而肯定不止有一项,例如 1 6 2 5 ,当求第四项的递推值时,有{1,5},]和{2,5}可选,{2,5}的值必然会大,因为f[3]的值是2 ,为{1},{1,2}中长度的最大值也就是{1,2},
如此进行递推,那么从f递推数组中取最大值 ,因为f[i]代表的是以第i项为结尾的,最长长度的上升子序列,所以求得的 就是该序列中最长的上升子序列,
代码
#include<iostream>
using namespace std;
const int N = 1010;
int g[N],f[N];
int main(){
int n;
cin>>n;
for(int i = 1;i <= n;i++){
cin>>g[i];
f[i] = 1;
}
for(int i = 1;i<=n;i++){
for(int j = 1;j<i;j++){
if(g[i]>g[j])f[i] = max(f[i],f[j]+1);
}
}
int ans = 0;
for(int i = 1;i<=n;i++)ans = max(ans,f[i]);
cout<<ans;
}