AcWing 895. 最长上升子序列

题目传送门

一、动态规划

(动态规划) \(O(n^2)\)

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

状态计算(集合划分):\(j∈(0,1,2,..,i-1)\), 在\(w[i] > w[j]\)时,
\(f[i] = max(f[i], f[j] + 1)\)

边界:若前面没有比\(i\)小的,\(f[i]\)\(1\)(自己为结尾)。

最后再找\(f[i]\)的最大值。

时间复杂度
\(O(n^2)\) 状态数(\(n\)) * 转移数( \(n\) )

二、C++ 代码

#include <bits/stdc++.h>

using namespace std;
const int N = 1010;

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

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) cin >> w[i];

    int mx = 0;    // 找出所计算的f[i]之中的最大值,边算边找
    for (int i = 0; i < n; i++) {
        f[i] = 1;    // 设f[i]默认为1,找不到前面数字小于自己的时候就为1
        for (int j = 0; j < i; j++)
            if (w[i] > w[j]) f[i] = max(f[i], f[j] + 1);    // 前一个小于自己的数结尾的最大上升子序列加上自己,即+1
        mx = max(mx, f[i]);
    }
    printf("%d", mx);
    return 0;
}

原文地址:https://www.cnblogs.com/littlehb/p/15425546.html