nyoj 214 单调递增子序列(二)

来源:互联网 发布:淘宝制作主图ps视频 编辑:程序博客网 时间:2024/06/06 00:30

单调递增子序列(二)

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
描述

给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序列,并求出其长度。

如:1 9 10 5 11 2 13的最长单调递增子序列是1 9 10 11 13,长度为5。

输入
有多组测试数据(<=7)
每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的下一行里有n个整数,表示数列中的所有元素.每个整形数中间用空格间隔开(0<n<=100000)。
数据以EOF结束 。
输入数据保证合法(全为int型整数)!
输出
对于每组测试数据输出整形数列的最长递增子序列的长度,每个输出占一行。
样例输入
71 9 10 5 11 2 1322 -1
样例输出
51
代码:

/*用 O(n^2)的经典动态规划会超时 #include<stdio.h>#include<string.h>#define N 100010int main(){ int n,i,j,max,res; int ans[N],MAX[N]; while(scanf("%d",&n)!=EOF) {  memset(ans,0,sizeof(ans));  memset(MAX,0,sizeof(MAX));  MAX[0]=1;  for(i=0;i<n;i++)   scanf("%d",&ans[i]);  for(i=1;i<n;i++)  {   max=MAX[i];   for(j=0;j<i;j++)   {    if(ans[i]>ans[j] && max<=MAX[j])    {     max=MAX[j]+1;     MAX[i]=max;    }   }  }  res=MAX[0];  for(i=0;i<n;i++)  {   if(res<MAX[i])    res=MAX[i];  }  printf("%d\n",res); } return 0;}

*///尝试用二分查找覆盖,时间复杂度降低 #include<stdio.h>#define N 100010#define INT 0x7fffffffint main(){ int n,i,ans[N],m; int top,low,high,mid; while(scanf("%d",&n)!=EOF) {  ans[0]=-INT;  top=0;  for(i=0;i<n;i++)  {   scanf("%d",&m);   if(m>ans[top])   {    top++;    ans[top]=m;   }   else   {    low=1;    high=top;    while(low<=high)    {     mid=(low+high)/2;     if(m>ans[mid])      low=mid+1;     else      high=mid-1;    }    ans[low]=m;   }  }  printf("%d\n",top); } return 0;}

 

 

 

原创粉丝点击