现在的位置: 首页 > 综合 > 正文

hdu 1025

2018年04月21日 ⁄ 综合 ⁄ 共 1058字 ⁄ 字号 评论关闭

大意就是给俩个数列 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>

 


【上篇】
【下篇】

抱歉!评论已关闭.