贪心——Luogu2255 [USACO14JAN]记录奥林比克

8 篇文章 0 订阅

题面:Luogu2255
显然是一个贪心嘛。。。慢慢分析

摄像机台数=1

这种情况,在当前时间我们只要找开始时间大于等于当前时间,结束时间尽量小的节目,这样才能留出更多时间拍后面的节目,所以排个序找一下就好了

摄像机台数=2

这种情况嘛。。。上面那个贪心就不对了,反例可以自己找一个(很好想的
但是按照这个思想是可以的,我们其实可以找当前空闲的摄像机拍是吧
有几种情况:

  1. 两台摄像机都在拍摄其他节目,这个时候显然不行
  2. 有一台摄像机空闲,那就选这台继续拍下去
  3. 两台都空闲,找两者结束之前拍摄较晚的继续拍下去,另外一台留给后面的拍,这样选择余地更多(浪费也少)

然后这题就可以做了,不过还有一个强化版。。。

强化版:摄像机台数<=n、记录方案

我们的某毒瘤模拟赛搞出来的
思路倒是也差不多,也是按照这样的选法贪心下去就可以了
按照原题数据范围也过了的
不过这样找摄像机的时间花费太多。。。我们可以把题目再强化一下,n<=100000
这样暴力找就GG,不过这个东西是可以用平衡树维护的
但是平衡树太麻烦了,STL的multiset就可以维护
至于记录方案,可以在选择摄像机的时候把选的节目记录下来,vector和链表都是可以的
上强化版代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstdlib>
#include<string>
#include<ctime>
#include<queue>
#include<set>
#include<climits>
#include<vector>
#define mp(i,j) make_pair(i,j)
using namespace std;
inline int read(){
    int k=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){k=k*10+ch-'0';ch=getchar();}
    return k*f;
}
multiset<pair<int,int> >s;
struct ppap{int l,r,x;}a[100001];
int n,m,ans=0;
vector<int>an[100001];
inline bool cmp(ppap a,ppap b){return a.r<b.r;}
int main()
{
    n=read();m=read();//m即为摄像机台数,原题m改为2即可
    for(int i=1;i<=n;i++)a[i].l=read(),a[i].r=read(),a[i].x=i;
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=m;i++)s.insert(mp(0,i));
    multiset<pair<int,int> >::iterator p;//迭代器
    for(int i=1;i<=n;i++){
        p=s.upper_bound(mp(a[i].l,1e9));
        if(p--!=s.begin()){
            ans++;int q=p->second;
            an[q].push_back(a[i].x);
            s.erase(p);s.insert(mp(a[i].r,q));
        }
    }
    printf("%d\n",ans);
    for(int i=1;i<=m;i++){
        int p=an[i].size();printf("%d ",p);
        for(int j=0;j<p;j++)printf("%d ",an[i][j]);
        puts("");
    }//原题方案不用输出哦
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值