大意就是给俩个数列 a1 b1 .a2 b2,a3 b3.。。。讲这些相连 最多能有多少没有交叉的
把俩个样例画下机会发现只要满足 Ai < AJ && Bi < Bj 那么就不会交叉
而且给的这些只要相连没有其他规定。。那么将A 或 B 从小到大排序,这时候就会满足AI < AJ 或者Bi < Bj 的情况。
看个人习惯吧。。我是习惯定A。。。然后就在左边找最多满足BI < BJ 的情况。。就会发现是求最长上升子序列的问题。。原本打算直接俩重循环。。后来发现N = 500000..只能用nlogn的方法才能过。nlong 的方法是 用到二分。关于这个的资料文库里面很多,也很好理解,动手模拟下就可以了。
尼玛。。然后输出坑爹啊。。居然还有分s的 还有要多输出一行、WA了2次,PE2次,。。
<span style="font-size:18px;">#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int const MAXN = 500010; int s[MAXN]; struct S{ int l,r; }a[MAXN]; int Binary_Search(int l,int r,int x){ while(l <= r){ int m =(l + r)>>1; if(s[m] > x) r = m - 1; else if(s[m] == x) return m; else l = m + 1; } return l; } bool cmp(S x,S y){ if(x.l != y.l) return x.l < y.l; return x.r < y.r; } int main(){ int k = 1,n; while(~scanf("%d",&n)){ for(int i = 1;i <= n;i++){ scanf("%d%d",&a[i].l,&a[i].r); } sort(a+1,a+n+1,cmp); s[0] = -1; int top = 0; for(int i = 1;i <= n;i++){ if(a[i].r > s[top]) s[++top] = a[i].r; else{ int m = Binary_Search(1,top,a[i].r); s[m] = a[i].r; } } printf("Case %d:\n",k++); if(top == 1) printf("My king, at most 1 road can be built.\n"); else printf("My king, at most %d roads can be built.\n",top); printf("\n"); } return 0; } </span>