题目链接:poj 3190 Stall Reservations
题目大意:有N只牛要挤奶,每个牛圈只能同时让一只奶牛挤奶,每只奶牛只在特定的A到B时间段产奶,问至少需要几个牛圈。
题解:贪心策略是优先满足A比较小的奶牛塞进B最小的牛栏,先将奶牛按照开始产奶的时间A_i从小到大排序,然后做一个牛圈的优先队列,以结束时间早的牛圈排在前,若塞不下则要新牛圈。网络上的解法,至今不理解为什么要优先满足A比较小的牛栏,这样不会造成一定的浪费导致不是最有解吗。
#include <iostream>
#include <algorithm>
#include <queue>
#include<cstdio>
using namespace std;
struct Section
{
unsigned int index;
unsigned int begin;
unsigned int end;
bool operator < (const Section& b) const
{
return begin < b.begin;
}
};
struct Stall
{
unsigned int id;
unsigned int end;
bool operator < (const Stall& b) const
{
return end > b.end;
}
};
#define MAX_COWS 50000
Section cow[MAX_COWS];
unsigned int result[MAX_COWS]; // 每头牛从属于哪个牛栏
priority_queue<Stall> que; // 最小堆,储存所有牛栏区间的结束点(也就是最右端)
inline void put_cow(const int& i, const bool& new_stall)
{
Stall s;
if (new_stall)
{
s.id = que.size() + 1;
}
else
{
s.id = que.top().id; que.pop();
}
s.end = cow[i].end;
result[cow[i].index] = s.id;
que.push(s);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int N;
cin >> N;
for (int i = 0; i < N; ++i)
{
cow[i].index = i;
cin >> cow[i].begin;
cin >> cow[i].end;
}
sort(cow, cow + N);
put_cow(0, true);
for (int i = 1; i < N; ++i)
{
put_cow (i, cow[i].begin <= que.top().end);
}
cout << que.size() << endl;
for (int i = 0; i < N; ++i)
{
cout << result[i] << endl;
}
return 0;
}
代码借鉴于:poj 3190 Stall Reservations.