任务

我觉得这道题目如果只有第一个问题的话,排序方式是多种多样的,而且考虑的对象也可以是机器

比如我可以给机器按照y从小到大排序,然后依次考虑每个机器,对于每个机器,在能选择的任务中选择x最大的即可

但这个时候就没有办法保证价值最大了,所以这道题启发我们,如果一道题目有多维的因素需要考量(这题目既要考虑任务个数又要考虑最终价值),对于多个对称的对象(比如这题的任务与机器,xy),我们要从每一个身上出发,去寻找符合题意的考虑对象

而且对于数字也要敏感,这道题目的两个加权数相差如此之大,我们要有一个感性的理解,要优先考虑x,再对y排序(证明见下)

而且为了价值最大,我们要以任务为考虑目标,这样就能保证能选的任务尽量被选择

此时,我们用数学归纳法来证明一下:假设已经选择的任务是最优方案的一部分,对于最新考虑的任务,如果他能够被完成,那么是一定会被完成的,问题就在于他要选择哪一个机器完成,显然是选择y值最小的完成,因为此时按照x递减排序,x已经不再是一个考虑因素。那么按照这种方案选择下来,看起来方案是唯一的,为什么就刚好能够保证价值最大呢?其实,对于最新考虑的任务,他之所以能被完成就一定被完成,是因为这样才保证第一个条件满足,然而他不被完成第一个条件一定不能够被满足吗?当然也不是,所以这就是这个方案的不唯一性。然而,我就算不完成这个任务,而去完成后面的任务导致第一个条件被满足了,但由于y的差值最大是100,乘以2也就是200,远小于500,所以这么选就刚好保证了价值最大(当然此时也有可能x不变,但是我们对x不变的任务是按照y从大到小排序的,此时y一定会减少)

所以我们可以直接考虑我们已经选择的任务是满足两个条件的最优方案的一部分(前面都只考虑了满足第一个条件),然后进行证明

如果我们以机器为考虑对象,那对于一个机器就应该会在其能够完成的任务中尽量选择y最大的(此时没有考虑x),就有可能不能够让价值最大了

而且此时甚至连第一个条件都无法保证。实际上,如果从小到大排序就必须以机器为考虑对象,从大到小排序就必须以任务为考虑对象,这样才可以满足依次考虑后才可以满足第一个条件

update 2025.1.8

也可以以机器为考虑的对象,做法如下:将机器按照y递增排序,扫描机器,对于当前的机器,找出所有y不大于当前机器y的任务,再在里面找出x最大且不大于当前机器x的任务给当前机器做就可以了

这个写法要对multiset重载小于运算符,可见如下代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m;
struct Node
{
	ll x,y;
	bool operator<(const Node &a) const
	{
	    if(a.x==x) return a.y<y;
		return a.x<x;
	}
	//这里的排序规则是,按照x递减排序,如果x相同就按照y递减排序
}mac[100010],ta[100010];
ll ans;
int cnt;
multiset<Node> s;
set<Node>::iterator it;
bool cmp(Node i,Node j)
{
	return i.y<j.y;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld%lld",&mac[i].x,&mac[i].y);
	}
	sort(mac+1,mac+n+1,cmp);
	for(int i=1;i<=m;i++)
	{
		scanf("%lld%lld",&ta[i].x,&ta[i].y);
	}
	sort(ta+1,ta+m+1,cmp);
	int flag=1;
	for(int i=1;i<=n;i++)
	{
		while(ta[flag].y<=mac[i].y&&flag<=m)
		{
			s.insert(ta[flag]);
			flag++;
		}
		if(!s.empty())
		{
			if((it=s.lower_bound(mac[i]))!=s.end())
			{
				ans+=500*(*it).x+2*(*it).y;
				s.erase(it);
				cnt++;
			}
		}
	}
	printf("%d %lld",cnt,ans);
    return 0;
}
posted @   最爱丁珰  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示