题目大意:
给你n头牛挤奶的时间段,同一时间同一栏内只能有一只牛问最少需要几个栏。并输出每头牛挤奶时所在的栏编号;
解题思路:
一开始就想的是找到区间重叠最大的数量,发现有点难找到这个值。
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define maxn 1010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(x,y) memset(x,y,sizeof(x))
#define rep(i,n) for(int i=0;i<(n);i++)
#define repf(i,a,b) for(int i=(a);i<=(b);i++)
#define pii pair<int,int>
//#define mp make_pair
#define FI first
#define SE second
#define IT iterator
#define PB push_back
#define Times 10
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int ,int > P;
const double eps = 1e-10;
const double pi = acos(-1.0);
const ll mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const ll INF = (ll)1e18+300;
const int maxd = 50500 + 10;
int n;
struct node{
int l, r;
int ii;
node(int ll = 0, int rr = 0):l(ll), r(rr){}
bool operator < (const node& p1)const {
return l < p1.l;
}
};
node ac[maxd];
int ans[maxd];
int main(){
cin >> n;
for (int i = 0; i < n; i ++) {
cin >> ac[i].l >> ac[i].r;
ac[i].ii = i;
}
sort(ac, ac+n);
priority_queue<P, vector<P>, greater<P> > que;
que.push(P(ac[0].r, 1));
int num = 0;
int cnt = 0;
ans[ac[0].ii] = 1;
int max_id = 1;
for (int i = 1; i < n; i++) {
P p = que.top();
int tim = p.first;
int id = p.second;
//cout << tim << " " <<ac[i].l << " " << ac[i].ii + 1 << endl;
if(tim >= ac[i].l) {
//cout << "**" << endl;
que.push(P(ac[i].r, max_id + 1));
ans[ac[i].ii] = max_id + 1;
max_id ++;
}
else {
que.pop();
//cout << "++" << endl;
ans[ac[i].ii] = id;
que.push(P(ac[i].r, id));
}
}
cout << max_id << endl;
for (int i = 0; i < n; i++) {
cout << ans[i] << endl;
}
}
又想到了可以每次找到最先完成的畜栏,在进行对比,若结束时间早就将新的牛放到这一栏中,否则重开一个畜栏。
有一点要注意的就是,如果你这头牛需要新开一个畜栏的话,之前结束时间最早的是不应该从队列中删除的。
AC代码: