O(n^2)
DP,f[i]代表第i个数字最多排第几位,然后遍历所有数字得到答案即可
j是从0开始遍历的 ,每次到0的时候都会加1,相当于赋初值了
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int a[N], f[N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
f[i] = 1;
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < i; j++)
if (a[i] > a[j])
f[a[i]] = max(f[a[i]], f[a[j]] + 1);
}
int res = 0;
for (int i = 1; i <= n; i++)
{
res = max(f[a[i]], res);
}
cout << res;
}
O(nlogn) 二分+贪心
遍历每个数,如果该数大于low中第一个元素,那么low中res+1,并且存该数。因为low数组中有个递增的性质,那么我们可以用二分 找到第一个大于等于该数的数的位置并且替换。得到一个更加优的low数组
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int low[N], a[N];
const int INF = 0x3f3f3f3f;
int n, ans;
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i], low[i] = INF;
low[1] = a[1];
ans = 1;
for (int i = 2; i <= n; i++)
{
if (a[i] > low[ans])
low[++ans] = a[i];
else
low[lower_bound(low + 1, low + 1 + ans, a[i]) - low] = a[i];
}
cout << ans;
}