E - Entertainment Box

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 k different TV shows simultaneously, and whenever a show recorded in one the machine’s k 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
The first line of input contains two integers n,k (1≤k<n≤100 000). Then follow n lines, each containing two integers xi,yi, meaning that show i starts at time xi and finishes by time yi. This means that two shows i and j, where yi=xj, can be recorded, without conflict, in the same recording slot. You may assume that 0≤xi<yi≤1 000 000 000.

Output
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.

Sample Input 1 Sample Output 1
3 1
1 2
2 3
2 3
2
Sample Input 2 Sample Output 2
4 1
1 3
4 6
7 8
2 5
3
Sample Input 3 Sample Output 3
5 2
1 4
5 9
2 7
3 8
6 10
3
题意:就是k个卡槽,每个卡槽可以录制一个视频,一个卡槽上的录制结束了马上可以录制下一个,问最多可以录制多少个视频。
这个题我感觉和其他做过的贪心不太一样,做了很长一段时间wa了很多次,最后看了网上的题解才回了,主要多了一个选择在哪个插槽的过程。
其实想想可以知道,应该是以每一个视频为研究对象,看看他插在哪个插槽最合适。可以知道应该插在那个距离上一个结束时间最短的时候这样可以使得每一个插槽的利用率最大,所以此时可以又最优解。
下面时WA代码。

#include<stdio.h>
#include<iostream>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
#define ll long long
const int N=1e5+10;
ll a[N];
struct node
{
    ll be;
    ll en;
    bool operator <(node &a)
    {
        if(en!=a.en)
        return en<a.en;
        else
        return be>a.be;
    }
}b[N];
int main()
{
    ll n,k,i,j;
    cin>>n>>k;
    for(i=1;i<=n;i++)
    {
        cin>>b[i].be>>b[i].en;
    }
    sort(b+1,b+1+n);
    priority_queue<ll,vector<ll>,greater<ll> > que;
    for(i=1;i<=k;i++)
    {
        que.push(b[i].en);
    }
    ll ans=k;
    for(i=k+1;i<=n;i++)
    {
        while(!que.empty())
        {
            ll q=que.top();
            if(b[i].be>=q)
                que.pop();
            else
                break;
        }
        ll quede=k-que.size();
        for(j=i;j<=i+quede-1;j++)
            que.push(b[j].en);
        if(quede>0)
            i=i+quede-1;
        ans+=quede;
    }
    printf("%lld\n",ans);
    return 0;
}

错误思路:这个题我就是想现在每个插槽里面插k个视频,最后从k+1个视频开始,只要有,就更新,这样虽保证了每个插槽上都有视频,但是只是乱插,不能保证最优,而且这个代码用的是优先队列,假设第一个就小于但是后面的大于的话就直接跳出,所以必定错误。
下面是AC代码;

#include<stdio.h>
#include<iostream>
#include<string>
#include<algorithm>
#include<set>
using namespace std;
#define ll long long
const int N=1e5+10;
ll a[N];
struct node
{
    ll be;
    ll en;
    bool operator <(node &a)
    {
        if(en!=a.en)
        return en<a.en;
    }
}b[N];
int main()
{
    ll n,k,i,j;
    cin>>n>>k;
    multiset<int> se;
    for(i=1;i<=n;i++)
    {
        cin>>b[i].be>>b[i].en;
    }
    std::multiset<int>::iterator it;
    sort(b+1,b+1+n);
    for(i=1;i<=k;i++)
    {
        se.insert(0);
    }
    ll ans=0;
    for(i=1;i<=n;i++)
    {
        it=se.upper_bound(b[i].be);
        if(it==se.begin())
            continue;
        else
        {
            it--;
            se.erase(it);
            se.insert(b[i].en);
            ans++;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

思路:用multiset,可以排序,也可以找到第一个大于的位置,最后插进去。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值