一、动态规划
(动态规划) \(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;
}