zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    Spring1()
    常用的比较器:实现方式Compareable和Comparator
    数据结构 2(数据结构 逻辑关系 存储关系 数据类型 抽象数据类型)
    面试题目
    数据结构(1术语)
    第一次作业-四则运算题目生成程序
    第二次 作业——APP案例分析
    面试题
    字符串转换时间的方法
    安卓获取手机内存,SD卡内存使用状态的方法
  • 原文地址:https://www.cnblogs.com/sevenun/p/5434431.html
Copyright © 2011-2022 走看看