hdoj 1025 Constructing Roads In JGShining's Kingdom(最长上升子序列+二分)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1025
View Code
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define maxn 500010 5 using namespace std; 6 int a[maxn]; 7 int b[maxn];//存储序列长度为len的第i小的数中最小的数 8 int dp[maxn]; 9 int chazhao(int x,int l,int r)//查找第i-1的长度序列中,结尾比a[i]小的最大长度 10 { 11 int mid; 12 while(l<=r) 13 { 14 mid=(l+r)/2; 15 if(b[mid]<=x) 16 l=mid+1; 17 else 18 r=mid-1; 19 } 20 return r; 21 } 22 int main() 23 { 24 int x,y,i,n,k=0,len; 25 while(scanf("%d",&n)!=EOF) 26 { 27 k++; 28 for(i=0;i<n;i++) 29 { 30 scanf("%d%d",&x,&y); 31 a[x]=y; 32 } 33 memset(b,-1,sizeof(b)); 34 dp[1]=1; 35 b[1]=a[1]; 36 len=1; 37 for(i=2;i<=n;i++) 38 { 39 int max=chazhao(a[i],1,len); 40 dp[i]=max+1; 41 if(b[i]==-1||b[dp[i]]>a[i])//更新b 42 b[dp[i]]=a[i]; 43 if(len<dp[i]) 44 len=dp[i]; 45 } 46 if(len==1) 47 { 48 printf("Case %d:\n",k); 49 printf("My king, at most %d road can be built.\n\n",len); 50 } 51 else 52 { 53 printf("Case %d:\n",k); 54 printf("My king, at most %d roads can be built.\n\n",len); 55 } 56 57 } 58 return 0; 59 }