[HDOJ 4864] Task [贪心]

69 篇文章 0 订阅
3 篇文章 0 订阅

现有n个机器和m个任务,每个机器有最大运行时间和等级,每个任务有需要运行时间和等级。一个机器只能运行一个任务,一个任务也仅能被一个机器运行,不能拆开由多个机器运行。每个机器只能运行等级和需要时间都小于等于它的任务。问最多可以运行多少个任务?在此前提下,最多可以得到多少分?

由于分数的公式是500*运行时间+2*等级,而且等级最大为100,所以相当于运行时间为第一关键字,等级为第二关键字

贪心,将机器和任务都排序,对于每个机器,按照等级从底到高的顺序,执行它可以执行的分数最高的任务即可。

#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>

using namespace std;

struct PP {
	int x,y;
	friend bool operator < (const PP &a,const PP &b) {
		return a.y<b.y;
	}
};
PP task[100101];
PP mach[100101];
struct SETPP {
	int i;
	SETPP() {}
	SETPP(int ii) {
		i=ii;
	}
	friend bool operator < (const SETPP &a,const SETPP &b) {
		//printf("%d %d %d %d %d %d\n",a.i,task[a.i].x,task[a.i].y,b.i,task[b.i].x,task[b.i].y);
		if (task[a.i].x!=task[b.i].x) return task[a.i].x>task[b.i].x;
		return task[a.i].y>task[b.i].y;
	}
};
multiset <SETPP> c;
int n,m;

int main() {
	int i,j,ansn;
	long long ans;
	while (scanf("%d%d",&n,&m)!=EOF) {
		for (i=0;i<n;i++) {
			scanf("%d%d",&mach[i].x,&mach[i].y);
		}
		for (i=0;i<m;i++) {
			scanf("%d%d",&task[i].x,&task[i].y);
		}
		sort(mach,mach+n);
		sort(task,task+m);
		j=0;
		ans=0;
		ansn=0;
		c.clear();
		for (i=0;i<n;i++) {
			while (j<m&&task[j].y<=mach[i].y) {
				c.insert(SETPP(j));
				j++;
			}
			multiset <SETPP> :: iterator k;
			//for (multiset <SETPP> :: iterator it=c.begin();it!=c.end();it++) {
				//printf("%d\n",it->i);
			//}
			task[m]=mach[i];
			k=c.lower_bound(SETPP(m));
			if (k!=c.end()) {
				ans+=500ll*task[k->i].x+2*task[k->i].y;
				c.erase(k);
				ansn++;
			}
		}
		printf("%d %I64d\n",ansn,ans);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值