HDU-4864-Task

HDU-4864-Task

传送门

这是一道贪心题目哦~

题目大意:给你几台机器,给你几个任务,每台机器有自己限制的工作时长和自己的等级,每个任务也有完成所需的工作时长和自己的等级,一台机器如果想要解决一个任务,必须满足这台机器对应的等级大于等于这个任务对应的等级,这台机器对应的工作时长也需要大于等于这个任务的工作时长,并且每台机器每天只能处理一项任务,一台机器处理完一项任务所获得的利润是500工作时长+2工作等级。问一天可以获得的最大利润是多少。

本题思路:很明显,是一道贪心,我们把时长和等级保存在结构体当中,然后排序,把工作时长长的放在前面,也就是降序,等级高的也放在前面,也是降序,因为每一台机器一天只能处理一个工作嘛,于是我们可以尽可能的找任务和机器时长和等级相匹配的结合在一起,之后的任务(因为是降序),于是那些等级高的机器也是可以完成的,我们用s[]数组记录:下标记录机器的等级,如果s[] > 0,那么就代表有任务可以处理。
判断条件:j < n && ma[j].x >= tas[i].x;
j代表机器遍历,我们把先开始把所以可以处理难搞的任务的机器记录下来,储存在s[]数组当中。然后到选择一台合适的机器处理当前任务,我们就从当前任务相同的等级开始,一直往上遍历,如果s[] > 0,就代表可以处理该任务,我们这里不需要担心时间问题,因为时间都是按照降序处理的,只要s[] > 0,那么说明前面有任务的时间小于等于机器的时间,我们就不需要担心。
这样维护一个ans就行啦~
这就是可以获得最大的利润啦~

代码部分:

#include <bits/stdc++.h>
#define mst(a, n) memset(a, n, sizeof(a))
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;

struct node
{
	int x, y;
	bool operator< (const node& r) const 
	{
		if (x != r.x)
		{
			return x > r.x;
		}
		else
		{
			return y > r.y;
		}
	}
}ma[N], tas[N];

int n, m;
int s[N];

int main()
{
	while (scanf ("%d%d", &n, &m) == 2)
	{
		for (int i = 0; i < n; i++)
		{
			scanf ("%d%d", &ma[i].x, &ma[i].y);
		}
		for (int i = 0; i < m; i++)
		{
			scanf ("%d%d", &tas[i].x, &tas[i].y);
		}
		sort(ma, ma + n);
		sort(tas, tas + m);
		int num = 0;
		ll ans = 0;
		mst(s, 0);
		int j = 0;
		for (int i = 0; i < m; i++)
		{
			while (j < n && ma[j].x >= tas[i].x)
			{
				s[ma[j].y]++;
				j++;
			}
			for (int k = tas[i].y; k <= 100; k++)
			{
				if (s[k] > 0)
				{
					num++;
					s[k]--;
					ans += 1ll * (500 * tas[i].x + 2 * tas[i].y);
					break;
				}
			}
		}
		cout << num << " " << ans << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

娃娃酱斯密酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值