任务(贪心)


第2题     任务 查看测评数据信息

今天公司有 m 项任务要完成。第 i 项任务需要 x[i] 分钟来完成。同时,这个任务有一个困难级别 y[i]。级别低于该任务级别 y[i] 的机器无法完成这项任务。如果公司完成了这项任务,他们将获得 (500* x[i]+2* y[i]) 美元。

公司有 n 台机器。每台机器都有最大工作时间和一个级别。如果任务的时间超过机器的最大工作时间,则该机器无法完成这个任务。每台机器一天只能完成一项任务。每项任务只能由一台机器完成。

公司希望最大化今天他们可以完成的任务数量。如果存在多个解决方案,他们希望使收益最大化。

输入格式

 

第一行包含两个整数 N 和 M。N 是机器的数量。M 是任务的数量 (1 <= N <= 100000, 1<= M<= 100000)。

接下来的 N 行每行包含两个整数 x[i](0<x[i]<1440),y[i](0<= y[i]<= 100)。x[i] 是机器可以工作的最长时间。y[i] 是机器的级别。

接下来的 M 行每行包含两个整数 x[i](0<x[i]<1440),y[i](0<= y[i]<= 100)。x[i] 是完成任务所需的时间。y[i] 是任务的级别。

 

输出格式

 

对于每个测试用例,输出两个整数,分别是公司今天可以完成的最大任务数量和他们将获得的收益。

 

输入/输出例子1

输入:

1 2 

100 3 

100 2 

100 1

 

输出:

1 50004

 

样例解释

 

贪心的值关于多个时,关注最重要的值,根据最重要的值贪心!

 

这是一道贪心好题。

可以看到这题中的关键变量有很多,但是要抓住其中一个最重要的,根据题目中的计算公式发现,时间才是最重要的(乘了500,等级撑死都打不过时间的贡献)

这是第一眼应该想到的,然后这种题要排个序,第一关键词当然是时间,然后考虑等级,因为贪心,还是比较容易想到的

排序完之后,我们根据每个任务来确定完成这个任务的机器,首先要看时间符不符合,由于任务时间是递减的,所以可以把符合的时间加入集合,并进一步判断

然后我们考虑找第一个大于等于这个任务等级的机器等级,毕竟集合内时间都是满足的,只用考虑等级,然而都有符合的了,肯定用一个最小的等级,留着大等级以后用,有一部分贪心思想

所以考虑用集合

 

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;

struct node
{
	long long x, y;
}a[N], b[N];
int n, m, h=0;
long long ans=0, cnt=0;
multiset<int> s;
multiset<int>::iterator it;
bool cmp(node a, node b)
{
    if (a.x==b.x) return a.y>b.y;
	return a.x>b.x;
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i=1; i<=n; i++) scanf("%lld%lld", &a[i].x, &a[i].y);
	for (int i=1; i<=m; i++) scanf("%lld%lld", &b[i].x, &b[i].y);
	
	sort(a+1, a+1+n, cmp);
	sort(b+1, b+1+m, cmp);
	
	h=1;
	for (int i=1; i<=m; i++)
	{
		for (int j=h; j<=n; j++)
		{
			if (a[j].x>=b[i].x)
			{
				s.insert(a[j].y);	
				if (j==n) h=j+1; //记得别漏判了,如果机器最后一台也符合,加入完后一定要更新记录完毕的下标值!!
			} 
			else 
			{
				h=j;
				break;
			}
		}
		
		it=s.lower_bound(b[i].y); 
		if ((it)!=(s.end()))
		{
			cnt++;
			ans+=500*b[i].x+2*b[i].y;
			s.erase(it);
		}
		
	}
	
	printf("%lld %lld", cnt, ans);
	return 0;
}
/*
3 2
98 1
99 5
100 1

99 5
100 1


3 2
100 1
99 5
98 1
100 1
99 5

*/

  

posted @ 2024-07-14 20:57  cn是大帅哥886  阅读(1)  评论(0编辑  收藏  举报