有哪位同学在POJ、洛谷或HDU上找到原题的请在评论区告知
AcWing访问量不是很可观
一眼看过去,
500
x
i
+
2
y
i
500x_i+2y_i
500xi+2yi这样的式子就让人很瞧不起
y
y
y
再看数据范围:
0
≤
y
i
≤
100
0\le y_i \le 100
0≤yi≤100
明显优先选择
x
x
x大的来做嘛!
y
y
y撑死了也没有一个
x
x
x的增加来的实在
由于机器的指标需要高于任务
我们选择给任务分配机器的形式
- 将机器与任务分别按照 x x x和 y y y先后排序
- 对于每个任务,我们记录 x x x大于它的机器(通过一个last指针扫描)
- 在所有 x x x大于它的机器中找到 y y y符合标准而最小的一台
- 更新答案
中间的第三步可以简化:
我们用一个
c
c
c数组记录符合
x
≥
x
n
o
w
t
a
s
k
x\ge x_{nowtask}
x≥xnowtask机器的个数
按照
y
y
y进行分类
每次寻找机器时让
j
j
j从当前任务的
y
y
y到
100
100
100枚举,如果有机器
y
=
j
y=j
y=j(表现为
c
[
j
]
≥
0
c[j]\ge 0
c[j]≥0)就标记该机器被使用(c[j]--
)并将本任务分配到这个机器
有点像计数排序的思想
代码如下:
#include<cstdio>
#include<algorithm>
#include<functional>
using namespace std;
struct node
{
int x,y;
}a[1110000]/*机器*/,b[1110000]/*任务*/;
int c[110];//c[j]指x大于当前任务的x且y等于j的机器数
bool operator >(const node a,const node b)//重载运算符
//排序要求传入const类型
{return a.x>b.x||a.x==b.x&&a.y>b.y;}//按照x值优先降序排序
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
for(int i=1;i<=m;i++)
scanf("%d%d",&b[i].x,&b[i].y);
sort(a+1,a+n+1,greater<node>());
//greater<node>()相当于 bool cmp(node a,node b){return a>b;}
sort(b+1,b+m+1,greater<node>());
int last=1,cnt=0;
long long ans=0;
for(int i=1;i<=m;i++)
{
while(a[last].x>=b[i].x)c[a[last++].y]++;//x符合标准的都可用
for(int j=b[i].y;j<=100;j++)//找到y符合标准而最小的一个
if(c[j])
{
c[j]--;
cnt++;
ans+=b[i].x*500+b[i].y*2;
break;
}
}
printf("%d %lld",cnt,ans);
return 0;
}