标签:inf pre i++ submit def std inpu scan 长度
如果一个数列ai 满足 a1 < a2 < ... < aN 则这个数列被称作上升序列。
给定一个数列a(a1, a2, ..., aN)则任意一个数列b(ai1, ai2, ..., aiK)并且满足(1 <= i1 < i2 < ... < iK <= N).则b被称为a的子序列。
如果一个数列的子序列是上升序列,则这个序列称为原序列的上升子序列。
比如序列(1, 7, 3, 5, 9, 4, 8)的上升子序列有(1, 7), (3, 4, 8)等. 它的最长上升子序列长度是4,即(1, 3, 5, 8).
请你写一个程序求一个序列的最长上升子序列的长度。
第一行是一个整数N表示给定数列的长度. 第二行包括N个范围在0~10000的整数。 1 <= N <= 1000
输出一个整数表示最长上升子序列的最大长度
7 1 7 3 5 9 4 8
4
#include<stdio.h> #include<algorithm> using namespace std; const int inf=1e9+7; int dp[41111];///dp[i] 最长上升子序列长度为i的时候 最小的尾数 int a[41111]; ///dp[pos]<=a[i]长度为pos的时候,最后一个数是<=a[i] ///dp[pos+1]=min(dp[pos+1],a[i]) ///dp[i]=MAX(dp[j]+1) j<i a[j]<a[i]; ///O(n^2)->O(n*log(n)) int efind(int s,int t,int x){ int l=s-1,r=t+1; while(l+1<r){ int mid=(l+r)/2; if(dp[mid]<=x) l=mid; else r=mid; } return l; }///找出第一个小于等于x的位置 int main(){ int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",a+i); dp[1]=a[1]; int top=1; for(int i=2;i<=n;i++){ int pos=efind(1,top,a[i]); if(pos==top){ top++; dp[top]=a[i]; }else{ dp[pos+1]=min(dp[pos+1],a[i]); } } printf("%d\n",top); } return 0; }
标签:inf pre i++ submit def std inpu scan 长度
原文地址:https://www.cnblogs.com/qq136155330/p/9052741.html