hdu4268 && 2012 Regional Changchun

题意:A, B各有n张牌,A要用自己的牌覆盖B的牌,求A最多能覆盖多少张。

            牌有长h和宽w两个属性,当一张牌能覆盖另一张牌,它的长宽都必须不小于另一张牌。

做法:将A,B的牌都按h由小到大排序,然后把B的所有不大于  A[ 0  ]的 h 的牌都放入multiset中(注意,扔掉h这一维,只放w即可),

            再在multiset中二分查找最后一张不大于 A[ 0 ] 的 w 的牌,找到一张最优的可覆盖的牌,将此牌删去,答案加1,之后以此类推。

#include <iostream>
#include <cstdio>
#include <set>
#include <algorithm>
using namespace std;

const int maxn = 111111;

multiset<int> mset;
int n;

struct Card {
    int h, w;
} A[maxn], B[maxn];

bool comp(const Card& a, const Card& b) {
    return a.h <= b.h;
}

int main()
{
    int T, i, j;

    scanf ("%d", &T);
    while (T--) {
        scanf ("%d", &n);
        for (i = 0; i < n; i++)
            scanf ("%d %d", &A[i].h, &A[i].w);
        for (i = 0; i < n; i++)
            scanf ("%d %d", &B[i].h, &B[i].w);
        sort(A, A+n, comp);
        sort(B, B+n, comp);
        int ans = 0;
        mset.clear();
        multiset<int>::iterator it;
        for (i = j = 0; i < n; i++) {
             while (j < n && B[j].h <= A[i].h) {
                mset.insert(B[j].w);
                j++;
             }
             if (!mset.empty()) {
                it = mset.upper_bound(A[i].w); //返回集合中大于A[i].w的第一个数的位置,返回值为迭代器类型
                if (it != mset.begin()) {
                   mset.erase(--it);
                   ans++;
                }
             }
        }
        printf ("%d\n", ans);
    }
    return 0
}


 

你可能感兴趣的:(hdu4268 && 2012 Regional Changchun)