线性dp:最长上升子序列Ⅰ

题目链接:https://www.acwing.com/problem/content/description/897/
给定一个长度为N的数列,求数值严格单调递增的子序列的长度最长是多少。
数据范围
1≤N≤1000,
−109≤数列中的数≤109
输入样例:
7
3 1 2 1 8 5 6
输出样例:
4
思路:时间复杂度O(n²)

  • 状态表示:f[i]表示从第一个数字开始算,以w[i]结尾的最大的上升序列。(以a[i]结尾的所有上升序列中属性为最大值的那一个)

  • 状态计算(集合划分):j∈(0,1,2,…,i-1), 在a[i] > a[j]时,
    f[i] = max(f[i], f[j] + 1)。有一个边界,若前面没有比i小的,f[i]为1(自己为结尾)。

  • 最后在找f[i]的最大值。
    在这里插入图片描述
    代码实现:

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN = 1000;
int a[MAXN],f[MAXN];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int n; scanf("%d", &n);
    for(int i = 1; i <= n; i ++ )
        scanf("%d", &a[i]);
    int ans = 0;
    for(int i = 1; i <= n; i ++ ){
        f[i] = 1;
        for(int j = 1; j < i; j ++ )
            if(a[j] < a[i])
                f[i] = max(f[i], f[j] + 1);
        ans = max(ans, f[i]);
    }
    printf("%d\n", ans);
    return 0;
}

发布了61 篇原创文章 · 获赞 0 · 访问量 982

猜你喜欢

转载自blog.csdn.net/Satur9/article/details/104025521