【每日算法】基础算法——最长上升子序列(七十三)

题目内容

给定一个长度为N的数列,求数值严格单调递增的子序列的长度最长是多少。

输入格式

第一行包含整数N。
第二行包含N个整数,表示完整序列。

输出格式

输出一个整数,表示最大长度。

数据范围

1≤N≤1000 ,
$−10^9$≤数列中的数≤$10^9$

输入样例

7
3 1 2 1 8 5 6

输出样例

4

题解

一、状态表示 f[i]
1、集合
所有以第i个数结尾的上升子序列
2、属性
集合中每一个上升子序列长度的最大值

二、状态计算
以第i-1位上的数来划分集合,可以有如下划分:
0/a[1]/a[2]/…/a[i-1]
但是,因为要求的是上升子序列,因此上述i类不一定全部存在。

f[i] = max(f[j]+1),j=0,1,2,…,i-1

代码

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010;

int n;
int a[N],f[N];

int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d",&a[i]);

for(int i = 1; i<= n; i++){
f[i] = 1; //只有a[i]一个数
for(int j = 1; j<i;j++){
if(a[j]<a[i])
f[i] = max(f[i],f[j]+1);
}
}
int res = 0;
for(int i=1;i<=n;i++) res = max(res,f[i]);
cout << res <<endl;
return 0;
}
Author: Frederic Niu
Link: https://www.fredericniu.cn/2021/02/23/【每日算法】基础算法——最长上升子序列(七十三)/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
我的公众号