hdu6003 Problem Buyer 贪心 给定n个区间,以及m个数,求从n个区间中任意选k个区间,满足m个数都能在k个区间中找到一个包含它的区间,如果一个区间包含了x,那么 该区间不能再去包含另一个数,即k>=m。求最小的k。如果不存在这样的k,输出“IMPOSSIBLE!”。

/**
题目:hdu6003 Problem Buyer
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6003
题意:给定n个区间,以及m个数,求从n个区间中任意选k个区间,满足m个数都能在k个区间中找到一个包含它的区间,如果一个区间包含了x,那么
该区间不能再去包含另一个数,即k>=m。求最小的k。如果不存在这样的k,输出“IMPOSSIBLE!”。

思路:贪心;
对n个区间,先左端点进行由小到大排序,然后右端点由大到小。对m个数由小到大排序。
对m个数进行枚举,设枚举数x,从排好序的区间左边开始找包含x的区间,放入优先队列q,那么队列里的都是包含x的区间,其他不包含它。
那么如果要满足题目要求,k>=n-q.size()+1;注意n-q.size()+1这个值不一定是该条件下m个数都能找到匹配区间的值,而是最少值。
因为剩下的n-q.size()不一定可以匹配所有的m-1个区间。可能有些数要匹配它的区间在q里面。不过没关系,只要这样进行下去,总会
找到一个最优值,详细证明,
大致说一下:
假设剩下的n-q.size()可以覆盖所有的m-1数,那么n-q.size()+1就是当前答案。
假设剩下的n-q.size()不可以覆盖所有的m-1数:
分两种情况。
1,剩下的某个数存在永远无法包含它的区间,那么可以解决,具体看代码,当为-1的时候,表示该数永远包含不到。
2,假设x个数在剩下的n-q.size()个区间无法包含,那么该x个数可以包含他们的区间在q里面。如果x+1>q.size(),那么-1,可以解决。
如果x+1<=q.size()。那么当前的n-q.size()+1不是当前答案,而是可能的至少值。随着向右进行(看代码),q.size()不断变化,总会存在一个最优的情况
使得q里面的区间只包含m正在枚举的这个数。

。具体看代码实现。


*/

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
typedef pair<int,int> P;
typedef long long LL;
const int N = 1e5+100;
const int INF = 0x3f3f3f3f;
struct node
{
    int l, r;
    bool operator < (const node&k)const{
        if(l==k.l) return r>k.r;
        return l<k.l;
    }
}t[N];
int c[N];
int main()
{
    int T, n, m;
    int cas = 1;
    cin>>T;
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i = 0; i < n; i++){
            scanf("%d%d",&t[i].l,&t[i].r);
        }
        for(int i = 0; i < m; i++) scanf("%d",&c[i]);
        sort(t,t+n);
        sort(c,c+m);
        priority_queue<int, vector<int>, greater<int> > q;
        int pos = 0;
        int ans = 0;
        for(int i = 0; i < m; i++){
            while(pos<n&&t[pos].l<=c[i]){
                if(t[pos].r>=c[i])
                    q.push(t[pos].r);
                pos++;
            }
            while(!q.empty()&&q.top()<c[i]) q.pop();
            if(q.empty()){
                ans = -1; break;
            }
            ans = max(ans,n-(int)q.size()+1);
            q.pop();
        }
        if(ans==-1) printf("Case #%d: IMPOSSIBLE!\n",cas++);
        else printf("Case #%d: %d\n",cas++,ans);
    }
    return 0;
}

 

posted on 2017-07-27 10:51  hnust_accqx  阅读(1289)  评论(0编辑  收藏  举报

导航