贪心算法--畜栏保留问题(poj3190 )

畜栏保留问题

总时间限制: 
1000ms 
内存限制: 
65536kB
描述

农场有N头牛,每头牛会在一个特定的时间区间[A, B](包括AB)在畜栏里挤奶,且一个畜栏里同时只能有一头牛在挤奶。现在农场主希望知道最少几个畜栏能满足上述要求,并要求给出每头牛被安排的方案。对于多种可行方案,主要输出一种即可。

输入
输入的第一行包含一个整数N(1 ≤ N ≤ 50, 000),表示有N牛头;接下来N行每行包含两个数,分别表示这头牛的挤奶时间[Ai, Bi](1 ≤ A≤ B ≤ 1, 000, 000)。
输出
输出的第一行包含一个整数,表示最少需要的畜栏数;接下来N行,第i+1行描述了第i头牛所被分配的畜栏编号(从1开始)。
样例输入
5
1 10
2 4
3 6
5 8
4 7
样例输出
4
1
2
3
2
4

这也是一个贪心的算法,在我看来贪心算法,就是平时这么用平常的思维解决问题,在贪心算法中,证明贪心算法我觉得是最难的部分,可是用平时的思维去思考的话,其实,你会发现其实,不用证明好像就是对的;

1) 把所有奶牛按开始时间从小到大排序。
2) 为第一头奶牛分配一个畜栏。
3) 依次处理后面每头奶牛i。处理 i 时,考虑已分配畜栏中,结束时间最早的畜栏x

E(x) < S(i), 则不用分配新畜栏,i可进入x,并修改E(x)E(i)E(x) >= S(i),则分配新畜栏y,E(y) = E(i)

直到所有奶牛处理结束

需要用优先队列存放已经分配的畜栏,并使得结束时间最早的畜栏始终 位于队列头部。 

这里第搜索畜栏有没有空的,最好使用STL中的优先队列,这样时间复杂度才是nlogn,这样才能勉强过;

ps:在poj上c++编译能过,g++不能过;

#include<iostream>
#include <queue>

using namespace std;
#define NUM 50005

struct cow{
    int f;
    int e;//挤奶区间起终点
    int NO;//编号
    bool operator<(const struct cow  &t) const{
        return this->f<t.f;
    }
}Cow[NUM];
int result[NUM];//表示编号为i的奶牛去的畜栏编号

struct Fence
{
    int k;//开始
    int j;//结束
    int NO;//栅栏编号;
    bool operator<(const Fence &t)const{
        return this->j>t.j;//先用时间结束晚的;
    }
    Fence(){};
    Fence(int x,int y,int n):k(x),j(y),NO(n){}
};




int main()
{
    int N;
    cin>>N;
    for(int i = 0;i<N;i++)
        {cin>>Cow[i].f>>Cow[i].e;  Cow[i].NO = i;}

//    for(int i = 0;i<N;i++)
//        {cout <<Cow[i].f<<" "<<Cow[i].e<<" "<< Cow[i].NO<<endl;}
    sort(Cow, Cow+N);

//    for(int i = 0;i<N;i++)
//        {cout <<Cow[i].f<<" "<<Cow[i].e<<" "<< Cow[i].NO<<endl;}



    int totle = 0;
    priority_queue<Fence > pq;
    for(int i = 0;i<N;i++){
        if(pq.empty()){
            totle++;
            pq.push(Fence(Cow[i].f,Cow[i].e,totle));
            result[Cow[i].NO] = totle;
        }
        else{
            Fence tt = pq.top();
            if(tt.j<Cow[i].f){
                pq.pop();
                result[Cow[i].NO] = tt.NO;
                pq.push(Fence(Cow[i].f,Cow[i].e,tt.NO));
            }
            else{
                totle++;
                pq.push(Fence(Cow[i].f,Cow[i].e,totle));
                result[Cow[i].NO] = totle;
            }
        }


    }
    cout <<totle<<endl;
    for(int i = 0;i < N;++i)
        cout <<result[i]<<endl;




    return 0;
}

    原文作者:贪心算法
    原文地址: https://blog.csdn.net/Randyhe_/article/details/78645115
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞