1 /***************************************************** 2 题目: 小明系列问题——小明序列(hdu 4521) 3 链接: http://acm.hdu.edu.cn/showproblem.php?pid=4521 4 算法: LIS最长上升子序列 5 6 ******************************************************/ 7 #include<cstdio> 8 #include<cstring> 9 #include<algorithm> 10 #include<iostream> 11 #include<queue> 12 using namespace std; 13 14 const int mx=100005; 15 int d[mx],dp[mx],a[mx]; 16 queue<int>q; 17 18 int BinSerch(int l,int r,int cut) 19 { 20 while (l<=r) 21 { 22 int m=(l+r)>>1; 23 if (cut>d[m]&&cut<=d[m+1]) return m; 24 if (cut>d[m]) l=m+1; 25 else r=m-1; 26 } 27 return 0; 28 } 29 30 int LIS(int n,int k) 31 { 32 int len=1,j; 33 fill(d,d+n+3,mx); 34 d[1]=a[0]; 35 for (int i=k+1;i<n;i++) 36 { 37 if (a[i]>d[len]) j=len+1; 38 else j=BinSerch(1,len,a[i])+1; 39 dp[i]=j; 40 q.push(i); 41 42 int cut=q.front(); 43 44 q.pop(); 45 d[dp[cut]]=min(a[cut],d[dp[cut]]); 46 len=max(len,dp[cut]); 47 } 48 while (!q.empty()) 49 { 50 int cut=q.front(); 51 q.pop(); 52 len=max(len,dp[cut]); 53 } 54 return len; 55 } 56 57 int main() 58 { 59 int n,d; 60 while (~scanf("%d%d",&n,&d)) 61 { 62 while (!q.empty()) q.pop(); 63 for (int i=0;i<n;i++) scanf("%d",&a[i]); 64 for (int i=1;i<=d;i++) 65 { 66 dp[i]=1; 67 q.push(i); 68 } 69 printf("%d\n",LIS(n,d)); 70 } 71 }