题目链接
题目很长,但要问的问题很简单,就是经典的求最长上升子序列问题,但是使用递推关系 dp[i]=max{1,dp[j]+1 | j<i && aj<ai } 时间复杂度O(n^2),题目中p < 40000,显然TLE。
P65~66 《挑战程序设计》
初始化dp[i]为inf,从头往后插入a[i],比较大小dp[i]=min(dp[i],a[i])后更新,对于每次更新,不必逐个遍历,采用二分搜索(STL中的lower_bound函数)
#include<iostream>
#include<algorithm>
inf 0x3f3f3f3f
using namespace std;
int main()
{
int n,m;
int a[40001];
int dp[40001];
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&m);
for(int j=1;j<=m;j++)
{
scanf("%d",&a[j]);
}
fill(dp,dp+m,inf);
for(int j=1;j<=m;j++)
{
*lower_bound(dp,dp+m,a[j])=a[j];
}
printf("%d\n",lower_bound(dp,dp+m,inf)-dp);
}
return 0;
}