CCPC E Problem Buyer

本文探讨了一种区间覆盖问题,目标是最小化选取的区间数,以确保所有点都能被至少一个区间覆盖。通过从左至右扫描并删除每个点对应的最左端合法区间的策略,实现了问题的有效解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

有一些区间,还有一些点。

问最小的k使得选出任意k个区间,每个点都可以匹配上区间,一个区间只能匹配一次。

题解

考虑对于每一个点,我们有\(x\)个区间包含它,那么答案的一个下界是\(n-x+1\)

但是这样没有考虑到一个区间被两个点匹配的情况。

那么我们从左到右做,没到一个点,就把右端点最靠左的合法区间删掉,可以证明这也是下界且可以达到。

代码

#include<bits/stdc++.h>
using namespace std;
#define N 100002
typedef long long ll;
int c[N],n,m;
int cnt;
inline ll rd(){
    ll x=0;char c=getchar();bool f=0;
    while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return f?-x:x;
}
struct node{
    int l,r;
    inline bool operator <(const node &b)const{
        return r>b.r;
    }
}a[N];
priority_queue<node>q;
inline bool cmp(node a,node b){
    if(a.l!=b.l)return a.l<b.l;
    return a.r>b.r; 
}
inline void solve(){
    while(!q.empty())q.pop();
    n=rd();m=rd();
    for(int i=1;i<=n;++i){
        a[i].l=rd();a[i].r=rd();
    }
    for(int i=1;i<=m;++i)c[i]=rd();
    sort(c+1,c+m+1);
    sort(a+1,a+n+1,cmp);
    int p=0;
    int ans=0;
    for(int i=1;i<=m;++i){
        while(p<n&&a[p+1].l<=c[i])p++,q.push(a[p]);
        while(!q.empty()&&q.top().r<c[i])q.pop();
        ans=max(ans,n-(int)q.size()+1);if(q.size())q.pop();
    }
    ++cnt;
    if(ans>n)printf("Case #%d: IMPOSSIBLE!\n",cnt);
    else printf("Case #%d: %d\n",cnt,ans);
}
int main(){
    int T=rd();
    while(T--)solve();
    return 0;
}

转载于:https://www.cnblogs.com/ZH-comld/p/11004987.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值