任务
我觉得这道题目如果只有第一个问题的话,排序方式是多种多样的,而且考虑的对象也可以是机器
比如我可以给机器按照
但这个时候就没有办法保证价值最大了,所以这道题启发我们,如果一道题目有多维的因素需要考量(这题目既要考虑任务个数又要考虑最终价值),对于多个对称的对象(比如这题的任务与机器,
而且对于数字也要敏感,这道题目的两个加权数相差如此之大,我们要有一个感性的理解,要优先考虑
而且为了价值最大,我们要以任务为考虑目标,这样就能保证能选的任务尽量被选择
此时,我们用数学归纳法来证明一下:假设已经选择的任务是最优方案的一部分,对于最新考虑的任务,如果他能够被完成,那么是一定会被完成的,问题就在于他要选择哪一个机器完成,显然是选择
所以我们可以直接考虑我们已经选择的任务是满足两个条件的最优方案的一部分(前面都只考虑了满足第一个条件),然后进行证明
如果我们以机器为考虑对象,那对于一个机器就应该会在其能够完成的任务中尽量选择
而且此时甚至连第一个条件都无法保证。实际上,如果从小到大排序就必须以机器为考虑对象,从大到小排序就必须以任务为考虑对象,这样才可以满足依次考虑后才可以满足第一个条件
update 2025.1.8
也可以以机器为考虑的对象,做法如下:将机器按照
这个写法要对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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构