YbtOJ——贪心算法【例题3】畜栏预定

C. 【例题3】畜栏预定

题目链接
内存限制:256 MiB
时间限制:1000 ms
标准输入输出
题目类型:传统
评测方式:Special Judge

题目描述

有 n 头牛在畜栏中吃草。每个畜栏在同一时间段只能提供给一头牛吃草,所以可能会需要多个畜栏,给出第 i 头牛开始吃草的时间区间 [ a i , b i ] [a_i,b_i] [ai,bi] ,求需要的最少畜栏数和每头牛对应的畜栏方案。

输入格式

第一行一个正整数 n。

接下来 n 行,第 i 行两个正整数 a i , b i a_i,b_i ai,bi

输出格式

第一行一个整数n,表示需要的最少畜栏数。

接下来 n 行,第 i 行一个整数表示第 i 头牛的对应畜栏,编号是从 1 开始的连续整数,方案合法即可。

样例

样例输入

5
1 10
2 4
3 6
5 8
4 7

样例输出

4
1
2
3
2
4

数据范围与提示

对于 % 100 \%100 %100 的数据,有 1 ≤ N ≤ 5 × 1 0 4 , 1 ≤ a i , b i ≤ 1 0 6 1\leq N\leq5×10^4,1\leq a_i,b_i\leq10^6 1N5×104,1ai,bi106

题解

牛按 a i a_i ai排序,再依次枚举,
对于每一头牛,若当前没有可用畜栏,则新加一个畜栏;
若有,则用,并维护这个畜栏的牛吃草的结束时间。
可用小根堆来找出吃草结束时间最早的畜栏,
于是时间复杂度可优化成 O ( n log ⁡ n ) O(n\log n) O(nlogn)

代码

#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
ll n,ans[100001];
struct que
{
	ll r;
	ll id;
	bool operator < (const que &a) const
	{
		return r>a.r;
	}
};
priority_queue <que> q;
struct node
{
	int l,r,id;
} a[100001];
ll cmp(node x,node y)
{
	return x.l<y.l;
}
int main()
{
	cin>>n;
	for(int i=1; i<=n; i++)
	{
		cin>>a[i].l>>a[i].r;
		a[i].id=i;
	}
	sort(a,a+n+1,cmp);
	for(int i=1; i<=n; i++)
	{
		if(!q.size()||q.top().r>=a[i].l)//若没有可用畜栏,新加畜栏
		{
			ans[a[i].id]=q.size()+1;
			q.push((que){a[i].r,q.size()+1});
		}
		else
		{
			ans[a[i].id]=q.top().id;
			q.pop();
			q.push((que){a[i].r,ans[a[i].id]});
		}
	}
	cout<<q.size()<<endl;
	for(int i=1; i<=n; i++)
	{
		cout<<ans[i]<<endl;
	}
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值