• [HNOI2004]宠物收养所


    题目大意:
      宠物收养所中每个宠物和人都有一个权值。一开始宠物收养所中没有东西。按顺序加入一些人和宠物。按照如下的规则进行收养:
      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
    ",ans);
    39     return 0;
    40 }
  • 相关阅读:
    利用URL protocol在网页打开本地exe
    [Leetcode]50. Pow(x, n)
    【转载】初识google test
    MySQL主从配置【转载】
    MySQL源码安装(centos)
    MySQL数据库MyISAM和InnoDB存储引擎的比较【转载】
    MySQL 事务
    MySQL 对于千万级的大表要怎么优化
    MySQL性能优化的最佳21条经验【转载】
    mysql日志详细解析【转载】
  • 原文地址:https://www.cnblogs.com/skylee03/p/8454419.html
Copyright © 2020-2023  润新知