hdu 1025 n*logn最长上升子序列
2014-11-16 22:51
246 查看
/* TLE */ #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn=5e5+5; int a[maxn],b[maxn],c[maxn],f[maxn<<1]; inline int max(int a,int b){return a>b?a:b;} void swap(int &a,int &b){int t=a;a=b;b=t;} void qsort(int l,int r) { if(l<r) { int key=b[l],i=l,j=r; while(i!=j) { while(b[j]>=key && i<j) j--; while(b[i]<=key && i<j) i++; if(i<j) swap(b[i],b[j]); } b[l]=b[i];b[i]=key; qsort(l,i-1); qsort(i+1,r); } } int binary_search(int l,int r,int val) { int mid; while(l<=r) { mid=(l+r)>>1; if(c[mid]>val) r=mid-1; else if(c[mid]==val) return mid; else l=mid+1; } return -1; } void updata(int pos,int v,int l,int r,int rt) { if(l==r) { f[rt]=v;return; } int mid=(l+r)>>1; if(pos<=mid) updata(pos,v,l,mid,rt<<1); else updata(pos,v,mid+1,r,rt<<1|1); } int query(int L,int R,int l,int r,int rt) { if(L<=l && r<=R) return f[rt]; int mid=(l+r)>>1; int ans; if(L<=mid) ans=query(L,R,l,mid,rt<<1); if(R>mid) ans=max(ans,query(L,R,mid+1,r,rt<<1|1)); return ans; } int main() { int icase=0,n,tmp,i,cnt; while(~scanf("%d",&n)) { for(i=1;i<=n;i++) { scanf("%d%d",&tmp,a+i);b[i]=a[i]; } qsort(1,n);cnt=1;c[1]=b[1]; for(i=2;i<=n;i++) if(b[i]!=b[i-1]) c[++cnt]=b[i]; memset(f,0,sizeof(f)); int ans=0,maxv,x; for(i=1;i<=n;i++) { x=binary_search(1,cnt,a[i]); if(x>1) maxv=query(1,x-1,1,cnt,1); else maxv=0; updata(x,maxv+1,1,cnt,1); if(maxv+1>ans) ans=maxv+1; } printf("Case %d:\n",++icase); if(ans==1) printf("My king, at most 1 road can be built.\n\n"); else printf("My king, at most %d roads can be built.\n\n",ans); } return 0; } /* 2 1 2 2 1 3 1 2 2 3 3 1 */
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn=5e+5; int dp[maxn],f[maxn]; int upper_bound(int l,int r,int val)//二分求上界 { int mid,ans=-1; while(l<=r) { mid=(l+r)>>1; if(dp[mid]>=val) ans=mid,r=mid-1; else l=mid+1; } return ans; } int main() { int icase=0,n,i,cnt,x,y; while(~scanf("%d",&n)) { for(i=1;i<=n;i++) { scanf("%d%d",&x,&y); f[x]=y; } dp[1]=f[1];cnt=1; for(i=1;i<=n;i++) { x=upper_bound(1,cnt,f[i]); if(x==-1) dp[++cnt]=f[i]; else dp[x]=f[i]; } printf("Case %d:\n",++icase); if(cnt==1) printf("My king, at most 1 road can be built.\n\n"); else printf("My king, at most %d roads can be built.\n\n",cnt); } return 0; }
相关文章推荐
- HDU 1025.Constructing Roads In JGShining's Kingdom【最长上升子序列n×logn算法】【1月6】
- HDU 1025 Constructing Roads (最长上升子序列O(n*logn)算法)
- hdu 1025 最长上升子序列+排序
- hdu 1025 Constructing Roads In JGShining's Kingdom 深夜又一波DP,最长上升子序列(O(nlogn)算法)!尼玛坑爹的输出啊!!
- HDU 1025 最长上升子序列
- hdu 1025 Constructing Roads In JGShining's Kingdom 最长上升子序列(nlogn)
- HDU 1025 Constructing Roads In JGShining's Kingdom(最长上升子序列O(nlogn))
- HDU 1025 最长上升子序列变形 (dp+二分)
- 【最长上升子序列O(nlgn)】HDU 1025
- HDU 1025 —— Constructing Roads In JGShining's Kingdom 最长上升子序列
- HDU 1025 最长上升子序列(nlogn)
- HDU-1025-动规-最长上升子序列
- HDU-1025 Constructing Roads In JGShining's Kingdom O(nlogn)的最长上升子序列
- HDU 1025 Constructing Roads In JGShining's Kingdom(LIS最长上升子序列)
- hdu 1025 最长严格上升子序列
- HDU 1025 A - Constructing Roads In JGShining's Kingdom(最长上升子序列)
- 算法代码hdu 1025(最大上升子序列的n*logn解法)
- HDU-1025,最长上升子序列(nlogn)算法+详解
- hdu 1025 Constructing Roads In JGShining's Kingdom(即求最长上升子序列)
- 动态规划之编号动态规划:hdu 1025(dp+二分 求最长上升子序列)