法一:DP 复杂度O(n)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cmath>
#define ll long long
using namespace std;
const int maxn = 103, INF = 0x7f7f7f7f;
ll a[maxn], dp[maxn];
ll n,ans = -INF;
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>a[i];
dp[i] = 1;
}
for(int i=1; i<=n; i++)
for(int j=1; j<i; j++)
if(a[j] < a[i])
dp[i] = max(dp[i], dp[j]+1);
for(int i=1; i<=n; i++)
ans = max(ans, dp[i]);
cout<<ans<<endl;
return 0;
}
法二:贪心+二分 复杂度o(nlogn)
用一个数组tmp[N]记录长度为i的LIS结尾元素的最小值 每次二分查找原数组元素a[i]在其中的位置,该位置即为ans
# include <iostream>
# include <cmath>
# include <cstdio>
# include <queue>
#include<cstring>
#include<algorithm>
#include <string>
#define ll long long
#define inf 2e18
using namespace std;
const int N=10;
ll ans[N],tmp[N],a[N];
// tmp[N]表示长度为i的LIS结尾元素的最小值 a[N]为原始序列 ans[N]表示到i的最长上升子序列长度
int main(){
fill(tmp, tmp+N, inf);
ll maxn=-1,n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=0;i<n;i++){
ll loc=lower_bound(tmp, tmp+n, a[i])-tmp;
ans[i]=loc+1;
tmp[loc]=a[i];
maxn=max(maxn,ans[i]);
}
cout<<maxn<<endl;
return 0;
}