贪心算法 - 挤奶问题

Posted memorylost

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贪心算法 - 挤奶问题相关的知识,希望对你有一定的参考价值。

/*
题目内容:有n头牛(1<=n<=50,000)要挤奶。
给定每头牛挤奶的时间区间[A,B](1<=A<=B<=1,000,000,A,B为整数)。
牛需要呆在畜栏里才能挤奶。一个畜栏同一时间只能容纳一头牛。
问至少需要多少个畜栏,才能完成全部挤奶工作,以及每头牛都放哪个畜栏里?
注意:在同一个畜栏的两头牛,它们挤奶时间区间不能在端点重合。
输入格式:
第1行:一个正整数N;
第2..N+1行:第i+1行的两个整数给出第i头奶牛的挤奶时间。
输出格式:
第1行:需要畜栏的最小数;
第2..N+1行:第i+1行表示第i头奶牛被分配到的畜栏序号
输入样例:
5
1 10
2 4
3 6
5 8
4 7
输出样例:
4
1
2
3
2
4
*/

#include<iostream>

using namespace std;

//奶牛结构体
struct cow
{
    long start;                    //开始挤奶的时间
    long end;                    //结束挤奶的时间
    long bucketNum=-1;            //分配的奶桶编号
};

//奶桶结构体
struct bucket
{
    long sn;                    //编号
    bool inUse=false;            //正在使用的状态
    long latesUseEndTime=-1;    //上次结束使用的时间
};
//题目要求的数字太大了,用数组会栈溢出,而动态分配内存又比较麻烦,所以只好先用小的数目
const int MAXNUM = 50;

//根据给定的奶牛开始挤奶的时间,确定它对应的最早可用的已有的奶桶编号,如果没有则返回负数
long getFirstProperBucket(struct bucket buc[], long total, long startTime) {
    long ret = -1;                                    //若已经使用过的奶桶中没有可用的,则返回负数
    for (long i = 0; i < total; i++) {
        //如果上一次使用的结束时间比现在要求的开始时间早,则可用
        if (buc[i].latesUseEndTime < startTime) {
            ret = i;
            break;
        }
    }
    return ret;
}

//returns the total amount of buckets needed
int solve(struct cow cow[], long n) {

    struct bucket buc[MAXNUM];                        //奶桶数组,最多每头奶牛分配一个奶桶
    long total = 0;                                    //总共所需奶桶数目

    for (long i = 0; i < n; i++) {
        long b = getFirstProperBucket(buc, total, cow[i].start);    //获取一个编号
        if (b >= 0) {                                //如果是正数,代表可用        
        }
        else {                                        //如果是负数,不可用,则添加一个新的奶桶,再分配编号
            total++;
             b=getFirstProperBucket(buc, total, cow[i].start);
        }
        buc[b].latesUseEndTime = cow[i].end;        //将奶桶的上次使用结束时间标记上
        cow[i].bucketNum = b;                        //将奶桶编号记录到奶牛
    }
    return total;
}

int main() {
    struct cow cow[MAXNUM];                    //奶牛数组
    long n;                                    //奶牛数量

    cin >> n;

    //输入数据和初始化
    for (long i = 0; i < n; i++)
    {
        cin >> cow[i].start >> cow[i].end;
        cow[i].bucketNum = -1;
    }

    //所需的奶桶数目
    int num = solve(cow, n);

    cout << num << endl;

    //依次输出奶牛分配的奶桶编号
    for (long i = 0; i < n; i++) {
        cout << cow[i].bucketNum+1<<endl;
    }

    cin >> num;                                //VC中防止程序直接结束
    return 0;
}

 

以上是关于贪心算法 - 挤奶问题的主要内容,如果未能解决你的问题,请参考以下文章

贪心算法求解畜栏问题

贪心算法:划分字母区间

763. 划分字母区间-贪心算法

贪心算法----区间覆盖问题(POJ2376)

POJ 3190 Stall Reservations贪心

Contig|scaffold|N50|L50|NG50|贪心算法|de bruiji graph|