题意:自己慢慢读吧。大概就是道路两边建路,给出建路需求,要求两条路不能有交叉,问最多可以建多少条路。
题解:一看数据范围500000,应该是dp,再画个图模拟一下,发现实质就是求最长上升子序列,很自然的数据要求nlogn算法
算法讲解在之前写过,这里直接贴过来:点我哦
坑:输出两个坑,一个是road和roads的区别,还有一个是案例之间有空行
code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N = 500005; 6 int q[N]; 7 int stk[N]; 8 int BSearch(int l,int r, int c) 9 { 10 while(l<=r){//注意这里应该是定于的时候还要再判断一次。 11 int m = (l+r)>>1; 12 if(stk[m]==c) { 13 //printf("id = %d\n",m); 14 return m; 15 } 16 else if(stk[m]<c) l = m+1; 17 else if(stk[m]>c) r = m-1; 18 } 19 //printf("id = %d\n",l); 20 return l; 21 } 22 int main() 23 { 24 int n; 25 int c = 1; 26 while(~scanf("%d",&n)) 27 { 28 int cnt = 1; 29 int t1,t2; 30 memset(stk,-1,sizeof(stk)); 31 for(int i = 0; i < n; i++){ 32 scanf("%d%d",&t1,&t2); 33 q[t1] = t2; 34 } 35 for(int i = 1; i <= n; i++){ 36 if(q[i]>stk[cnt-1]){ 37 stk[cnt++] = q[i]; 38 } 39 else { 40 int id = BSearch(1,cnt-1,q[i]); 41 stk[id] = q[i]; 42 } 43 } 44 cnt--; 45 if(cnt!=1) 46 printf("Case %d:\nMy king, at most %d roads can be built.\n\n",c++,cnt); 47 else 48 printf("Case %d:\nMy king, at most %d road can be built.\n\n",c++,cnt); 49 } 50 return 0; 51 }