LIS解析:
LIS 是 longest Increasing Sequence
是一道典型的线性DP问题,有两种算法可以求
一种是n^2 的算法,
设a: 1-n 的序列
for i 1->n
for j 1->i dp[i] = 1
d[i] = max{dp[i],dp[j]+1(a[j] < a[i])}
另一种nlogn即可(隐形DP)
设a: 1-n 的序列
设b 记录长度为i子序列的最小尾数的序列//次序列单调
for i 1 -> n
k++ 或 binary;
AC code:
#include <iostream>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int maxn = 4e4 + 100;
int a[maxn];
int b[maxn];
int binary(int st, int ed,int x)
{
int mid;
while(ed - st > 1)
{
mid = st + (ed-st)/2;
if(b[mid] == x) return mid;
if(b[mid] < x) st = mid;
else ed = mid;
}
return ed;
}
int LIS(int p)
{
int k = 1;
memset(b,0,sizeof(0));
b[1] = a[0];
for(int i = 1; i < p; i++)
{
int x = a[i];
if(x > b[k]) b[++k] = x;
else if(x < b[1]) b[1] = x;
else
{
int j = binary(1,k,x);
b[j] = min(b[j],x);
}
}
return k;
}
int main()
{
int n,p;
scanf("%d",&n);
while(n--)
{
scanf("%d",&p);
for(int i = 0; i < p; i++)
{
scanf("%d",&a[i]);
}
int ans = LIS(p);
printf("%d\n",ans);
}
return 0;
}