poj 3190 Stall Reservations 贪心 + 优先队列

题意:给定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;
}

  

原文地址:https://www.cnblogs.com/sevenun/p/5434431.html