Acwing 最长上升子序列

发布时间 2023-10-19 21:09:47作者: Cheng_Mao

题目

给定一个长度为 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;
}