• 【和排序】 耍杂技的牛


    传送门

    题意

    (n)头牛,每头牛有重量(w_{i})和强壮程度(s_{i}),牛与牛之间垂直堆叠,每头牛的风险值是他上面不包括他自己所有牛的重量之和减他的强壮程度,求所有奶牛风险值中的最大值尽可能的小

    数据范围

    (egin{array}{l}1 leq N leq 50000 \ 1 leq w_{i} leq 10,000 \ 1 leq s_{i} leq 1,000,000,000end{array})

    题解

    贪心策略:按照(w)(s)的和进行排序
    贪心证明: 邻项交换
    假设排序后当前从下往上第(i)头牛和第(i+1)头牛的风险值分别为(sum_{j=0}^{i-1} w_{j}-s_{i} ,quad sum_{j=0}^{i} w_{j}-s_{i+1})
    交换这两头牛后的风险值分别为(sum_{j=0}^{i-1} w_{j}-s_{i+1},sum_{j=0}^{i-1} w_{j}+w_{i+1}-s_{i})
    去掉重复项(quad sum_{j=0}^{i-1} w_{i-1})后交换前和交换后的值分别为

    • 交换前:(-s_{i})(w_{i}-s_{i+1})
    • 交换后:(-s_{i+1})(w_{i+1}-s_{i})

    易知

    • (w_{i}-s_{i+1} > -s_{i+1})
    • (w_{i+1}-s_{i} > -s_{i})

    所以只需要比较(w_{i}-s_{i+1})(w_{i+1}-s_{i})的大小即可
    (w_{i}-s_{i+1} < w_{i+1}-s_{i})
    (w_{i} + s_{i} < w_{i+1} + s_{i+1})
    所以和越小的风险值越小

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,n) for(int i=a;i<n;i++)
    #define fi first 
    #define se second 
    #define ll long long
    typedef pair<long long,long long> pll;
    const int N=5e4+10;
    int n;
    pll cow[N];
    
    int main(){
        scanf("%d",&n);
        rep(i,0,n){
            ll x,y;
            scanf("%lld%lld",&x,&y);
            cow[i].fi=x+y;
            cow[i].se=y;
        }    
        sort(cow,cow+n);
        ll now=0;
        ll mx=-1e18;
        rep(i,0,n){
            mx=max(mx,now-cow[i].se);
            now+=cow[i].fi-cow[i].se;
        }
        printf("%lld
    ",mx);
    }
    
    
  • 相关阅读:
    实例讲解Springboot以Repository方式整合Redis
    Spark join 源码跟读记录
    数理统计与参数估计杂记
    常见的距离算法和相似度(相关系数)计算方法
    生成模型(Generative Model)与判别模型(Discriminative Model)
    Java 积累复习用
    RangePartitioner 实现简记
    Spark常见问题汇总
    2016年终总结
    学习资料库
  • 原文地址:https://www.cnblogs.com/hhyx/p/13208344.html
Copyright © 2020-2023  润新知