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;
    }
    

      

  • 相关阅读:
    English 2
    速算24点
    心理学1
    从微服务到函数式编程
    034 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 01 流程控制概述
    033 01 Android 零基础入门 01 Java基础语法 03 Java运算符 13 运算符和表达式知识点总结
    032 01 Android 零基础入门 01 Java基础语法 03 Java运算符 12 运算符和if-else条件语句的综合案例——闰年问题
    031 01 Android 零基础入门 01 Java基础语法 03 Java运算符 11 运算符的优先级
    030 01 Android 零基础入门 01 Java基础语法 03 Java运算符 10 条件运算符
    029 01 Android 零基础入门 01 Java基础语法 03 Java运算符 09 逻辑“非”运算符
  • 原文地址:https://www.cnblogs.com/sevenun/p/5434431.html
Copyright © 2011-2022 走看看