题意:给定N头奶牛,每头牛有固定的时间[a,b]让农夫去挤牛奶,农夫也只能在对应区间对指定奶牛进行挤奶,
求最少要多少个奶牛棚,使得在每个棚内的奶牛的挤奶时间不冲突。
思路:1、第一个想法就是贪心,对每头牛的挤奶时间[a,b]按a和b都从小排序,接着从左边开始找地一头牛,
然后再往右边找能够不冲突的牛再一个奶牛棚内。这个算法事件复杂度为n*n,由于最多5000头牛
所以后面还是TLE了。
2、还是自己太弱了,原来可以用优先队列进行优化,可以把当前冲突的牛放入优先队列,然后每次都能够冲优先队列
里面取出a最小的奶牛,所以自然就不用如算法1那样,要进行一个n的循环。所以算法最终复杂度就是nlogn。
AC代码:
#include <cstdio> #include <cstring> #include <queue> #include <iostream> #include <cmath> #include <algorithm> using namespace std; #define LL long long const int N = 50005; int t,d[N],n,k,ans[N]; struct node{ int s,e,id,stall; bool operator < (const node &a) const { return a.e < e; } }w[N]; bool cmp(node n1, node n2){ return n1.s < n2.s; } void solve(){ priority_queue<node > Q; sort(w,w+n, cmp); k = 0; int S = 2; node now; now.e= 0; now.stall = 1; Q.push(now); for(int i = 0; i < n; i++) { now = Q.top(); if(w[i].s > now.e) { Q.pop(); w[i].stall = now.stall; ans[w[i].id] = now.stall; Q.push(w[i]); }else { w[i].stall = S; ans[w[i].id] = S++; Q.push(w[i]); } } printf("%d ", S-1); for(int i = 0; i < n; i++) printf("%d ", ans[i]); } int main(){ //freopen("in.txt", "r", stdin); while(~scanf("%d", &n)){ for(int i = 0; i < n; i++){ scanf("%d %d", &w[i].s, &w[i].e); w[i].id =i; } solve(); } return 0; }
TLE代码:
#include <cstdio> #include <cstring> #include <queue> #include <iostream> #include <cmath> #include <algorithm> using namespace std; #define LL long long const int N = 50005; const int INF = 0X3F3F3F3F3F3F3F3F; int t,ans,d[N],n; struct node{ int s,e,id; }w[N]; bool cmp(node n1, node n2){ if(n1.s != n2.s) return n1.s < n2.s; else return n1.e > n2.e; } void init(){ } void solve(){ int k = 0; ans = 0; sort(w,w+n, cmp); bool vis[n]; memset(vis, false, sizeof vis); for(int i = 0; i < n; i++){ //这个循环n*n,所以TLE了,之前没留意,还以为因为sort函数 if(!vis[i]){ int end = w[i].e; int id = w[i].id; d[id] = ++k; for(int j = i+1; j < n; j++) if(!vis[j] && w[j].s > end){ vis[j] = true; d[w[j].id] = k; end = w[j].e; } } } printf("%d ", k); for(int i = 0; i < n; i++) printf("%d ", d[i]); } int main(){ //freopen("in.txt", "r", stdin); while(~scanf("%d", &n)){ for(int i = 0; i < n; i++) scanf("%d %d", &w[i].s, &w[i].e),w[i].id =i; solve(); } return 0; }