openjudge 百練 2757:最長上升子序列
- 總時間限制:
- 2000ms
- 內存限制:
- 65536kB
- 描述
-
一個數的序列
bi,當
b1 <
b2 < ... <
bS的時候,我們稱這個序列是上升的。對於給定的一個序列(
a1,
a2, ...,
aN),我們可以得到一些上升的子序列(
ai1,
ai2, ...,
aiK),這里1 <=
i1 <
i2 < ... <
iK <= N。比如,對於序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。這些子序列中最長的長度是4,比如子序列(1, 3, 5, 8).
你的任務,就是對於給定的序列,求出最長上升子序列的長度。 - 輸入
- 輸入的第一行是序列的長度N (1 <= N <= 1000)。第二行給出序列中的N個整數,這些整數的取值范圍都在0到10000。
- 輸出
- 最長上升子序列的長度。
- 樣例輸入
-
7 1 7 3 5 9 4 8
- 樣例輸出
- 4
1 /*再做做這道題是因為另一道題目是反利用這個c數組的,這里復習一下*/ 2 #include<iostream> 3 using namespace std; 4 #include<cstdio> 5 #include<cstring> 6 int n; 7 #define N 1010 8 int c[N],f[N],ans=-N,a[N]; 9 int search(int l,int r,int k) 10 { 11 if(l==r) return l; 12 int mid=(l+r+1)>>1;/*還有這里的+1*/ 13 if(c[mid]>=k) return search(l,mid-1,k);/*這里的mid-1是保證是上升序列*/ 14 else return search(mid,r,k); 15 } 16 int main() 17 { 18 scanf("%d",&n); 19 for(int i=1;i<=n;++i) 20 scanf("%d",&a[i]); 21 memset(f,0,sizeof(f)); 22 memset(c,127,sizeof(c)); 23 for(int i=1;i<=n;++i) 24 { 25 f[i]=search(0,i,a[i])+1;/*這里的具體二分過程最好自己手動模擬一下,以防出錯*/ 26 c[f[i]]=min(a[i],c[f[i]]); 27 ans=max(f[i],ans); 28 } 29 printf("%d\n",ans); 30 return 0; 31 }