其实题目是这个样子的:
仔细看能够知道,每条轨道上火车的编号都是递减的,这样就等价于求他的最大上升子序列的长度,由于N比较大,所以采用nlogn的LIS方法 f[i]表示长度为i的最长上升子序列最后一个最小为f[i],首先易证f[i]中存的数单调递增的 这样对于每个a[i],若a[i]>现有已知最长上升子序列的最后一个数,那么len++,f[len]=a[i] 否则 在1~len中二分,找到第一个比a[i]打的数f[j]吧f[j]更新成a[i]
1 #include <cstdio> 2 #include <cmath> 3 #include <cstdlib> 4 #include <cstring> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <iostream> 9 #include "algorithm" 10 #define mem(a,b) memset(a,b,sizeof(a)) 11 using namespace std; 12 typedef long long LL; 13 const int MAX=100005; 14 int n; 15 int a[MAX],f[MAX]; 16 int main(){ 17 freopen ("manage.in","r",stdin); 18 freopen ("manage.out","w",stdout); 19 int i,j; 20 int low,high,mid,len; 21 scanf("%d",&n); 22 for (i=1;i<=n;i++) 23 scanf("%d",a+i); 24 len=0; 25 for (i=1;i<=n;i++){ 26 if (a[i]>f[len]) 27 f[++len]=a[i]; 28 else{ 29 low=1;high=len-1; 30 while (low<=high){ 31 mid=(low+high)>>1; 32 if (f[mid]<=a[i]) 33 low=mid+1; 34 else 35 high=mid-1; 36 } 37 f[low]=a[i]; 38 } 39 } 40 printf("%d",len); 41 return 0; 42 }
其实是个模板题
时间: 2024-10-11 01:05:14