计蒜客暑假集训第七场 e题

Ada, Bertrand and Charles often argue over which TV shows to watch, and to avoid some of their fights they have finally decided to buy a video tape recorder. This fabulous, new device can record kk different TV shows simultaneously, and whenever a show recorded in one the machine's kk slots ends, the machine is immediately ready to record another show in the same slot.

The three friends wonder how many TV shows they can record during one day. They provide you with the TV guide for today's shows, and tell you the number of shows the machine can record simultaneously. How many shows can they record, using their recording machine? Count only shows that are recorded in their entirety.

Input Format

The first line of input contains two integers nn, kk (1 \le k < n \le 100 000)(1≤k<n≤100000). Then follow nn lines, each containing two integers x_i, y_ixi​,yi​, meaning that show ii starts at time x_ixi​ and finishes by time y_iyi​. This means that two shows iiand jj, where y_i = x_jyi​=xj​, can be recorded, without conflict, in the same recording slot. You may assume that 0 \le x_i < y_i \le 1 000 000 0000≤xi​<yi​≤1000000000.

Output Format

The output should contain exactly one line with a single integer: the maximum number of full shows from the TV guide that can be recorded with the tape recorder.

样例输入1

3 1
1 2
2 3
2 3

样例输出1

2

样例输入2

4 1
1 3
4 6
7 8
2 5

样例输出2

3

样例输入3

5 2
1 4
5 9
2 7
3 8
6 10

样例输出3

3

题目大意:

给你n个电视节目、录像机能够同时录的节目数和每个节目的开始时间,结束时间,问你录像机最多能够录几个节目。

思路:

贪心+模拟

这道题是活动选择题目的升级版,活动选择题目规定每个会场只能表演一个节目,但是这个题目就相当于一个会场可以同时表演多个节目,问你最多能够选择多少个活动。

我们首先按照结束时间从小到大排序,如果结束时间相同,那么按照开始时间从小到大排序。

我们用multiset容器进行模拟,首先介绍multiset容器是个啥?这是集合的升级版,集合能够将进来的元素去重、排序,而multiset只能够将进来的元素排序无法去重。我们规定multiset容器中存的是当前选泽的活动的结束时间,然后开始遍历其他的活动,如果当前所遍历的活动的开始时间大于所选择的活动的结束时间(只大于其中一个就可以,假设大于编号为i的活动的结束时间),我们就把当前所遍历的活动的结束时间放到muliset中去,覆盖掉i活动的结束时间。否则,就不往muliset中加入(即不选择这个活动)

注意:初始的时候我们往muliset中放入k个0。

代码:

​
​
#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
struct node
{
    int begin,end;
}a[MAXN];
int n,k;
multiset < int >q;
multiset < int >::iterator it;
bool cmp(node a,node b)//定义比较器
{
    if(a.end==b.end)
        return a.begin<b.begin;
    return a.end<b.end;
}
int main()
{
    cin>>n>>k;
    for(int i=0;i<n;i++)
        cin>>a[i].begin>>a[i].end;
    sort(a,a+n,cmp);
    for(int i=0;i<k;i++)
        q.insert(0);//往muliset中放入k个0
    int sum=0;
    for(int i=0;i<n;i++)
    {
        it=q.upper_bound(a[i].begin);//这句话的意思是找到容器中大于a[i].begin的第一个元素的位置
        if(it==q.begin())//如果这个条件满足,说明muliset中所有元素都大于a[i].begin,说明这个活动不选择
            continue ;
        it--;
        q.erase(it);//删除活动结束时间小于等于a[i].begin的结束时间最小的活动
        q.insert(a[i].end);//添加该活动的结束时间  这个地方删一个,加一个,可以保证muliset中始终有k个元素
        sum++;//计数
    }
    cout<<sum;
}

​

​

收获:

一:知道了set容器和muliset容器,知道了他们的性质及用法,具体的用法:

传送门:https://blog.csdn.net/CABI_ZGX/article/details/52193350

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值