[HNOI2004]宠物收养所

本文解析了一道关于宠物收养所的算法题,通过维护两棵平衡树,实现人与宠物之间的匹配过程,旨在最小化权值差异的总代价。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:
  宠物收养所中每个宠物和人都有一个权值。一开始宠物收养所中没有东西。按顺序加入一些人和宠物。按照如下的规则进行收养:
  1.若人来时没有宠物,则原地等待;
  2.若人来时有宠物,则选择权值最接近的宠物中权值最小的宠物进行收养,代价为两者权值差;
​  3.若宠物来时有人,那么分配给权值最接近的人中权值最小的人收养,代价为两者权值差。
思路:
  维护两棵平衡树,每次看一下对应的树中有没有结点。如果有,选择合适的计算代价,并从树上移除;如果没有,就将当前权值加入到另一棵树中。这显然可以用std::set维护。

 1 #include<set>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<climits>
 5 inline int getint() {
 6     register char ch;
 7     while(!isdigit(ch=getchar()));
 8     register int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return x; 
11 }
12 const int mod=1000000;
13 std::set<int> s[2];
14 int main() {
15     s[0].insert(INT_MIN);
16     s[0].insert(INT_MAX);
17     s[1].insert(INT_MIN);
18     s[1].insert(INT_MAX);
19     int ans=0;
20     for(register int i=getint();i;i--) {
21         const int opt=getint(),x=getint();
22         if(s[opt].size()==2) {
23             s[opt^1].insert(x);
24             continue;
25         }
26         const int l=*--s[opt].lower_bound(x);
27         const int r=*s[opt].lower_bound(x);
28         if(l==INT_MIN||(r!=INT_MAX&&x-l>r-x)) {
29             s[opt].erase(r);
30             ans+=r-x;
31         }
32         if(r==INT_MAX||(l!=INT_MIN&&x-l<=r-x)) {
33             s[opt].erase(l);
34             ans+=x-l;
35         }
36         ans%=mod;
37     }
38     printf("%d\n",ans);
39     return 0;
40 }

 

转载于:https://www.cnblogs.com/skylee03/p/8454419.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值