zoukankan      html  css  js  c++  java
  • 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!
    ",cas++);
            else printf("Case #%d: %d
    ",cas++,ans);
        }
        return 0;
    }
  • 相关阅读:
    DOS系统功能调用与BIOS中断调用 [转自KingofCoders]
    纯手工保护光盘数据(转)
    程序员不错的建议【转】
    初识逆向技术(转)
    Notepad++插件推荐JSMin
    jQuery Ready 与 Window onload 的区别
    Javascript typeof和instanceof判断数据类型
    浅谈Javascript 中几种克隆(clone)方式
    Javascript Array sort排序问题
    不同浏览器对display为none元素的图片处理不一样
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7243606.html
Copyright © 2011-2022 走看看