Stall Reservations (greedy, interval problem)

Stall Reservations

Oh those picky N (1 <= N <= 50,000) cows! They are so picky that each one will only be milked over some precise time interval A…B (1 <= A <= B <= 1,000,000), which includes both times A and B. Obviously, FJ must create a reservation system to determine which stall each cow can be assigned for her milking time. Of course, no cow will share such a private moment with other cows.

Help FJ by determining:
The minimum number of stalls required in the barn so that each cow can have her private milking period
An assignment of cows to these stalls over time
Many answers are correct for each test dataset; a program will grade your answer.
Input
Line 1: A single integer, N

Lines 2…N+1: Line i+1 describes cow i’s milking interval with two space-separated integers.
Output
Line 1: The minimum number of stalls the barn must have.

Lines 2…N+1: Line i+1 describes the stall to which cow i will be assigned for her milking period.
Sample Input
5
1 10
2 4
3 6
5 8
4 7
Sample Output
4
1
2
3
2
4
Hint
Explanation of the sample:

Here’s a graphical schedule for this output:

Time 1 2 3 4 5 6 7 8 9 10

Stall 1 c1>>>>>>>>>>>>>>>>>>>>>>>>>>>

Stall 2 … c2>>>>>> c4>>>>>>>>> … …

Stall 3 … … c3>>>>>>>>> … … … …

Stall 4 … … … c5>>>>>>>>> … … …
Other outputs using the same number of stalls are possible.

Title:

insert image description here

Thought analysis:

After a cow has been milked in a fence, the fence is left open and other cows can enter.
If a cow wants to be milked, but all the current fences are full, a new fence is opened; if not, the cow can go in.
That is to say, a basic idea is to traverse the start time of the cow (the time when it is ready to go in), and then look for an empty fence. If there is, the cow will go in; if not, open a new one. So we first sort the start times of the cows to make sure that the cows we traverse come in chronological order.
The key now is how to implement the step of "finding the empty fence". If we have to traverse all the fences for each cow, the time complexity is O(n^2). Here we can think about it with greedy thinking: if we want to know whether there is an empty fence, we only need to know whether the fence that ends the earliest is empty, that is, the end time of this fence is less than the start time of the cow. Each time we process it with the fence with the earliest end time and the current cow to deduce the global optimal solution.
Therefore, every time we traverse a cow, we need to know the end time of the earliest end fence, that is, we need to obtain a minimum end time in all fences at all times. Here you can think of using a minimum heap to achieve.
Therefore, for cow nodes there are: start time (s), end time (e), fence number (id2). For fence nodes there are: fence number (id), end time (e).
Since we output data according to The original cows are output in order, so we also need to add a cow's initial number (id) to the cow's node.
We first sort the cows by starting time, then traverse the cows, judge with the minimum heap, and then process them accordingly. Finally, according to the original number of cattle, row back from small to large, and output the data.

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm> 
using namespace std;

//至少需要多少个畜栏才能完成全部挤奶操作
//对奶牛按照开始时间升序排序
//奶牛存编号,开始时间和结束时间,栅栏编号 
//栅栏存结束时间和编号 
//用最小堆获取最早结束的栅栏
//之后按奶牛的编号排序,输出栅栏编号

struct cow{
    
    
	int id, id2;
	int s, e;
}; 

struct stall{
    
    
	int id, e;
	bool operator < (const stall &b) const{
    
    
		return e > b.e;
	}
};

bool cmp1(const cow &a, const cow &b)
{
    
    
	return a.s < b.s;
}

bool cmp2(const cow &a, const cow &b)
{
    
    
	return a.id < b.id;
}

int main()
{
    
    
	int n;
	while(~scanf("%d",&n))
	{
    
    
		vector<cow> a;
		cow t;
		stall tt;
		for(int i = 0;i < n;i++)
		{
    
    
			t.id = i;
			scanf("%d%d",&t.s, &t.e);
			a.push_back(t);
		}
		sort(a.begin(), a.end(), cmp1);
		priority_queue<stall> pq;
		int cnt = 0;
		for(int i = 0;i < n;i++)
		{
    
    
			if(pq.empty())
			{
    
    
				cnt++;
				a[i].id2 = cnt;
				tt.id = cnt, tt.e = a[i].e;
				pq.push(tt);
				continue;
			}
			if(pq.top().e < a[i].s) //有栅栏空着 
			{
    
    
				tt.e = a[i].e, tt.id = pq.top().id, a[i].id2 = tt.id;
				pq.pop();
				pq.push(tt);
			}
			else //栅栏都满了 
			{
    
    
				cnt++;
				tt.e = a[i].e, tt.id = cnt, a[i].id2 = tt.id;
				pq.push(tt);
			}
		} 
		sort(a.begin(), a.end(), cmp2);
		printf("%d\n",cnt);
		for(int i = 0;i < n;i++)
		{
    
    
			printf("%d\n",a[i].id2);
		}
	}
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325712917&siteId=291194637