hdu 4268 Alice and Bob multiset的应用

http://acm.hdu.edu.cn/showproblem.php?pid=4268

题意:
Alice and Bob各自都有N个矩形纸牌,Alice 想用他的纸牌尽量多的覆盖Bob的纸牌,i覆盖j满足的条件是p[i].h >= p[j].h   p[i].w >= p[j].w ,并且一张纸牌只能覆盖一张,求最多覆盖的张数。

思路:

这里给出的n很大, (N <= 100,000) 首先分析肯定回事O(nlogn)级别的算法,才开始我想到的是二分,分别将Alice and Bob的纸牌排序,枚举Alice的纸牌二分查找Bob的纸牌里最大的能满足被Alice 的纸牌覆盖的然后覆盖并将其删除,(贪心的找能覆盖的最大的这样就能够保证覆盖完之后覆盖的最多)。可能是我写搓了,老师tle可能在删除的时候我用的vector把,这相当于模拟了,应该不好,不过用multiset最好了,因为他是红黑树的平衡二叉检索树的数据结构,所以操作起来比较节约时间吧。

这里的处理,将Alice and Bob一同排序,若遇到Alice就往multiset里面查找,因为进去的都是满足被覆盖的且没有被覆盖的纸牌。

View Code
#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <cmath>

#include <queue>

#include <stack>

#include <set>

#include <map>

#include <string>



#define CL(a,num) memset((a),(num),sizeof(a))

#define iabs(x)  ((x) > 0 ? (x) : -(x))

#define Min(a,b) (a) > (b)? (b):(a)

#define Max(a,b) (a) > (b)? (a):(b)



#define ll __int64



#define MOD 100000007

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define test puts("<------------------->")

#define maxn 100007

#define M 10017

#define N 100007

using namespace std;



struct node{

    int h,w;

    int mk;

}p[2*N];



int n;



int cmp(node a,node b){

    if (a.h != b.h) return a.h < b.h;

    else if (a.w != b.w) return a.w < b.w;

    else return a.mk > b.mk;

}

multiset<int>S;



int GetInt()

{

    char ch = getchar();

    while (ch < '0' || ch > '9') ch =getchar();

    int num = 0;

    while (ch >= '0' && ch <= '9'){

        num = num*10 + ch - '0';

        ch = getchar();

    }

    return num;

}

int main(){

    //freopen("din.txt","r",stdin);

    int i;

    int t;

    scanf("%d",&t);

    while (t--){

        S.clear();

        scanf("%d",&n);

        for (i = 0; i < n; ++i){

            p[i].h = GetInt();

            p[i].w = GetInt();

            p[i].mk = 0;

        }

        for (; i < 2*n; ++i){

            p[i].h = GetInt();

            p[i].w = GetInt();

            p[i].mk = 1;

        }

        sort(p,p + 2*n,cmp);



        //for (i = 0; i < 2*n; ++i) printf(">>%d %d\n",p[i].h,p[i].w);



        int ans = 0;

        for (i = 0; i < 2*n; ++i){

            if (p[i].mk == 1) S.insert(p[i].w);//Bob进容器

            else{

                if (!S.empty()){//Alice查找

                    if (*S.begin() <= p[i].w){//查看是否具有查找的可能

                        multiset<int>::iterator it;

                        it = S.upper_bound(p[i].w);

                        it--;

                        ans++;

                        S.erase(it);

                    }

                }

            }

        }

        printf("%d\n",ans);

    }

    return 0;

}

 

 

 

你可能感兴趣的:(set)