任务

今天某公司有M个任务需要完成。

每个任务都有相应的难度级别和完成任务所需时间。

第i个任务的难度级别为yi,完成任务所需时间为xi分钟。

如果公司完成此任务,他们将获得(500 * xi + 2 * yi)美元收入。

该公司有N台机器,每台机器都有最长工作时间和级别。

如果任务所需时间超过机器的最长工作时间,则机器无法完成此任务。

如果任务难度级别超过机器的级别,则机器无法完成次任务。

每台机器一天内只能完成一项任务。

每个任务只能由一台机器完成。

请为他们设计一个任务分配方案,使得该公司能够最大化他们今天可以完成的任务数量。

如果有多种解决方案,他们希望选取赚取利润最高的那种。

输入格式

输入包含几个测试用例。

对于每个测试用例,第一行包含两个整数N和M,分别代表机器数量和任务数量。

接下来N行,每行包含两个整数xi,yi,分别代表机器最长工作时间和机器级别。

再接下来M行,每行包含两个整数xi,yi,分别代表完成任务所需时间和任务难度级别。

输出格式

对于每个测试用例,输出两个整数,代表公司今天可以完成的最大任务数以及他们将获得的收入。

数据范围

1≤N,M≤100000 ,
0<xi<1440,
0≤yi≤100

输入样例:

1 2
100 3
100 2
100 1

输出样例:

1 50004

思路:
刚开始看到这道题,觉得这是一个贪心,然后两个数字一组,很自然考虑到用pair去写,
那么问题,怎么贪?
通过要求的最大收入的表达是来看,x,y两个数,500*x + 2 y;看数据范围,y < 100; 2 * y < 200;
这个比500
x 要小,因此我们根据x来贪。
先输入,再根据时间从小到大排序;然后倒着做(贪心这么贪),把任务放在循环里,因为任务要做,机器可以有不用的,一个机器一天完成一个,先做任务时间长的,然后把这个>=这个时间的机器找出来,所有的都要找出来,然后再根据任务难度选择最合适的机器,然后任务数++,花费+=;同时把这个机器删除。

这个题输出的时候,犯了一个很低级的错误,我把输出放到循环里面了,最后给了我三个输出。额呃呃呃来表达一下我的心情

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
using namespace std;
const int maxn = 1e5 + 10;
typedef pair<int,int> PII;
PII a[maxn],b[maxn];
int N,M,x,y;
multiset<int> s;

int main()
{
	//机器数量和任务数量和任务数量
	while(scanf("%d%d",&N,&M)!=EOF)
	{
		for(int i = 1; i <= N; i++)
			//机器最长的工作时间和机器级别
			scanf("%d%d",&a[i].first,&a[i].second);
		for(int j = 1; j <= M; j++)
			//完成任务所需要的时间和难度
			scanf("%d%d",&b[j].first,&b[j].second);
		//排序,从小到大
		sort(a+1,a+N+1);
		sort(b+1,b+M+1);
		s.clear();
		//任务数量
		int cnt = 0;
		//收入
		long long ans = 0;
		//把所有的任务按照时间排列,i表示任务,j表示机器
		for(int i = M,j = N;i>=1; i--)
		{
			//任务的时间要比机器的时间短,即<=;还要考虑难度,因此把所有的都找出来,这时候找的是机器
			while(j >= 1 && b[i].first <= a[j].first)
				s.insert(a[j--].second);
			//先把大的数字放进去,set是从小到大排的,lower_bound找到的是第一个大于等于b[i].second的,
			auto it = s.lower_bound(b[i].second);
			if(it != s.end()){
				cnt++;
				ans += 500*b[i].first + 2 * b[i].second;
				//删除,找到it,删除这个机器,剩下的放在里面
				s.erase(it);
			}

		}
		printf("%d %lld",cnt,ans);
	}
	return 0;
}

补充:pair默认的两个first,second;
multiset允许重复,具有自动排序
遍历

set元素唯一,默认升序
遍历:

set<int> s;
for(auto it : s)
		cout << it;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章