题目1533:最长上升子序列 (nlogn | 树状数组)
题目1533:最长上升子序列
http://ac.jobdu.com/problem.php?pid=1533
时间限制:1 秒
内存限制:128 兆
特殊判题:否
提交:857
解决:178
- 题目描述:
-
给定一个整型数组, 求这个数组的最长严格递增子序列的长度。 譬如序列1 2 2 4 3 的最长严格递增子序列为1,2,4或1,2,3.他们的长度为3。
- 输入:
-
输入可能包含多个测试案例。
对于每个测试案例,输入的第一行为一个整数n(1<=n<=100000):代表将要输入的序列长度
输入的第二行包括n个整数,代表这个数组中的数字。整数均在int范围内。
- 输出:
-
对于每个测试案例,输出其最长严格递增子序列长度。
- 样例输入:
-
4 4 2 1 3 5 1 1 1 1 1
- 样例输出:
-
2 1
#include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; const int N=110000; int n,val[N]; vector<int> vt; int binarySearch(int x){ int left=0,right=vt.size()-1; int mid; while(left<=right){ mid=(left+right)>>1; if(vt[mid]<x) left=mid+1; else right=mid-1; } return left; } int main(){ //freopen("input.txt","r",stdin); while(~scanf("%d",&n)){ vt.clear(); for(int i=0;i<n;i++) scanf("%d",&val[i]); int tmp; for(int i=0;i<n;i++){ tmp=binarySearch(val[i]); if(tmp>=(int)vt.size()) vt.push_back(val[i]); else vt[tmp]=val[i]; } int ans=vt.size(); printf("%d\n",ans); } return 0; }
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=110000; int n,val[N],a[N]; int len,arr[N]; int lowbit(int x){ return x&(-x); } void update(int i,int x){ while(x<=len){ if(i>arr[x]) arr[x]=i; x+=lowbit(x); } } int query(int x){ int ans=0; while(x){ if(arr[x]>ans) ans=arr[x]; x-=lowbit(x); } return ans; } int main(){ freopen("input.txt","r",stdin); while(~scanf("%d",&n)){ for(int i=0;i<n;i++){ scanf("%d",&val[i]); a[i]=val[i]; } sort(a,a+n); len=unique(a,a+n)-a; memset(arr,0,sizeof(arr)); int ans=1,tmp; for(int i=0;i<n;i++){ val[i]=lower_bound(a,a+len,val[i])-a+1; tmp=query(val[i]-1)+1; if(tmp>ans) ans=tmp; update(tmp,val[i]); } printf("%d\n",ans); } return 0; }