工厂机器安排(贪心算法)

题目来源:HDOJ
一、题目介绍
Today the company has m tasks to complete. The ith task need xi minutes to complete. Meanwhile, this task has a difficulty level yi. The machine whose level below this task’s level yi cannot complete this task. If the company completes this task, they will get (500xi+2yi) dollars.

The company has n machines. Each machine has a maximum working time and a level. If the time for the task is more than the maximum working time of the machine, the machine can not complete this task. Each machine can only complete a task one day. Each task can only be completed by one machine.

The company hopes to maximize the number of the tasks which they can complete today. If there are multiple solutions, they hopes to make the money maximum.

输入格式:
The input contains several test cases.

The first line contains two integers N and M. N is the number of the machines.M is the number of tasks(1 < =N <= 100000,1<=M<=100000).

The following N lines each contains two integers xi(0<xi<1440),yi(0=<yi<=100).xi is the maximum time the machine can work.yi is the level of the machine.

The following M lines each contains two integers xi(0<xi<1440),yi(0=<yi<=100).xi is the time we need to complete the task.yi is the level of the task.

输出格式:
For each test case, output two integers, the maximum number of the tasks which the company can complete today and the money they will get.

输入样例:
在这里给出一组输入。例如:

1 2
100 3
100 2
100 1

输出样例:
在这里给出相应的输出。例如:

1 50004

二、分析
(1)n个机器,m个任务。
(2)机器和任务都有两个指标:时间xi,难度系数yi
(3)机器可以执行任务的充要条件:机器的两个指标分别不小于任务的两个指标
(4) 一天一个机器最多执行一个任务,求一天最多执行多少任务,前者有多种方案时,使得盈利最多
(5)任务被执行盈利:500xi+2yi
三、我的错误思路

	(1)以“时间作为第一指标,难度系数作为第二指标”将机器和任
	务分别降序排列。
	(2)从i=j=0开始,每一个任务i,若机器j可以执行,则执行,
	i++,j++下个任务,下个机器
	(3)若任务i不能被机器j执行,则必然不能被后面的机器执行,此
	时i++,判断下一任务

反例:若按照以上思路,则第二个任务不能被执行

taskm2(200,4)(100,5)
machinen2(200,5)(200,4)

四、正确思路

把所有时间大于等于任务的机器找出来,对于每个任务选取一个能完成它但难度y最小的机器来做。因为对于后面所有的任务,我们找出来的机器在时间上一定能完成,就看难度了。根据贪心的基本思想,潜力大的东西要留,所以如此。这样既能保证时间大的任务优先做,又能使各种难度的任务得到合适的分配。故其是优秀的贪心方案。

附上代码:

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

struct node
{
    int time;
    int level;
} mach[100000], task[100000];

int lev[105];

bool cmp(const node &a, const node &b)
{
    if (a.time == b.time)
        return a.level > b.level;

    return a.time > b.time;
}

int main()
{
    int m, n;
    while (cin >> n >> m)
    {
        int cnt = 0, j = 0;
        long long mon = 0; //数据量较大,防止溢出
        for (int i = 0; i < n; i++)
            cin >> mach[i].time >> mach[i].level;
        for (int i = 0; i < m; i++)
            cin >> task[i].time >> task[i].level;
        sort(mach, mach + n, cmp);
        sort(task, task + m, cmp);
        for (int i = 0; i < m; i++)
        {
            while (mach[j].time >= task[i].time && j < n)
            {
                lev[mach[j++].level]++;
            }
            for (int k = task[i].level;  k <= 100; k++)
            {
                if (lev[k])
                {
                    cnt++;
                    mon += 500 * task[i].time + 2 * task[i].level;
                    lev[k]--;
                    break;
                }
            }
        }
        cout << cnt << " " << mon << endl;
        memset(mach, 0, sizeof(node) * n);
        memset(task, 0, sizeof(node) * m);
        memset(lev, 0, sizeof(lev));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值