任務

今天某公司有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;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章