Task
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 400 Accepted Submission(s): 72
Problem Description
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 (500*xi+2*yi) 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 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.
Input
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.
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.
Output
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.
Sample Input
1 2 100 3 100 2 100 1
Sample Output
1 50004
Source
首先,我们可以确定这是一道贪心的题目。整个贪心的思路比赛时和队友也讨论了很久,最终确定了一个没有漏洞的:
将机器按照先等级,后时间的顺序排序,按顺序枚举机器。在枚举等级为yi的机器时,找到等级为0 到 yi的、时间最大且能被机器完成、等级尽量高的任务。
因为价值函数是500 * x + 2 * y, y的范围是0-100,所以时间越长必然是价值越大。
使用线段树维护等级为0到当前等级的所有任务,每次查找时间符合条件的最大值即可。因为同时要找等级较高的,所以将时间和等级按照 x*102-101+y 结合起来,查找时找区间0 到 x*102的最大值即可。
代码如下:
将机器按照先等级,后时间的顺序排序,按顺序枚举机器。在枚举等级为yi的机器时,找到等级为0 到 yi的、时间最大且能被机器完成、等级尽量高的任务。
因为价值函数是500 * x + 2 * y, y的范围是0-100,所以时间越长必然是价值越大。
使用线段树维护等级为0到当前等级的所有任务,每次查找时间符合条件的最大值即可。因为同时要找等级较高的,所以将时间和等级按照 x*102-101+y 结合起来,查找时找区间0 到 x*102的最大值即可。
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <string>
using namespace std;
#define ff(i, n) for(int i=0;i<(n);i++)
#define fff(i, n, m) for(int i=(n);i<=(m);i++)
#define dff(i, n, m) for(int i=(n);i>=(m);i--)
typedef long long LL;
typedef unsigned long long ULL;
void work();
int main()
{
#ifdef ACM
freopen("in.txt", "r", stdin);
#endif // ACM
work();
}
/***************************************************/
#define lson l, m, pos<<1
#define rson m+1, r, pos<<1|1
#define hehe 1, 200000, 1
const int maxn = 200000;
int ma[maxn<<2], num[maxn<<2];
void updateFather(int pos)
{
ma[pos] = max(ma[pos<<1], ma[pos<<1|1]);
}
void update(int p, int v, int l, int r, int pos)
{
if(l == r)
{
num[pos] += v;
if(num[pos])
ma[pos] = l;
else
ma[pos] = 0;
return;
}
int m = (l+r)/2;
if(p <= m)
update(p, v, lson);
else
update(p, v, rson);
updateFather(pos);
}
int query(int L, int R, int l, int r, int pos)
{
if(L<=l && r<=R)
return ma[pos];
int m = (l+r)/2;
return max(L<=m?query(L, R, lson):0, m<R?query(L, R, rson):0);
}
int cal(int x, int y)
{
return x*102-101+y;
}
void work()
{
int n, m;
while(~scanf("%d%d", &n, &m))
{
vector<int> machine[101];
vector<int> task[101];
int x, y;
ff(i, n)
scanf("%d%d", &x, &y), machine[y].push_back(x);
ff(i, m)
scanf("%d%d", &x, &y), task[y].push_back(x);
ff(i, 101)
sort(machine[i].begin(), machine[i].end());
memset(num, 0, sizeof(num));
memset(ma, 0, sizeof(ma));
int ans = 0;
LL money = 0;
ff(i, 101)
{
ff(j, task[i].size())
update(cal(task[i][j], i), 1, hehe);
ff(j, machine[i].size())
{
int x = machine[i][j];
int q = query(1, cal(x, 101), hehe);
if(q > 0)
{
update(q, -1, hehe);
ans++;
int xx = q/102+1;
int yy = q%102-1;
money += xx*500 + 2*yy;
}
}
}
printf("%d %I64d\n", ans, money);
}
}