zoukankan      html  css  js  c++  java
  • POJ3045

    题意

    给n只奶牛,每只奶牛都有两个属性, 风险值(s[i])和抗压值(w[i]),现在要把这些牛垒在一起, 每个牛都有一个危险值位他上面的牛的风险值之和减去它的抗压值,问最大危险值得最小值(n<=5e4,1 <= w[i]<= 1e4,1 <= s[i] <= 1,000,000,000 )

    分析

    二分? 怎么check(mid)?? 想不到

    正解:贪心 ,按照每头牛s[i] +w[i]之和排序,大的放下面(感性的想一下,似乎何有道理???)

    证明:现在考虑中间的任意两只 i 和 i+1只牛, 假设现在是最佳排列方式,现改变i和i+1头牛的顺序,由于前面和后面都不受影响,所以可以单独考虑

    现默认从上到下为第1~n头牛,设前i-1头牛的总风险值为W

    未改变:

    第i个位置:W-w[i]

    第i+1位置:   W+s[i] - w[i+1]    -----1

    改变后:

    第i个位置: W-w[i+1]

    第i+1位置:  W+s[i+1]-w[i]   ------2

    方程1 < 方程2 可以推出   s[i] + w[i] < s[i+1] + w[i+1]  

    #include <cstdio>
    #include <iostream>
    #include <queue>
    #include <algorithm>
    #include <cstring>
    #include <set>
    using namespace std;
    #define ll long long
    
    const int maxn = 1e5 + 10;
    
    
    struct node
    {
        int w, s;
        friend bool operator < (node a, node b)
        {
            return a.w+a.s < b.w+b.s;
        }
    }a[maxn];
    int n;
    
    int main()
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d%d", &a[i].w, &a[i].s);
        }
        sort(a+1,a+n+1);
        ll sum = -1ll*a[1].s;
        ll ans=1ll*a[1].w;
        for(int i = 2; i <= n; i++)
        {
            sum=max(sum, 1ll*(ans-a[i].s));
            ans+=1ll*a[i].w;
        }
        printf("%lld
    ", sum);
        return 0;
    }
    View Code
    要么优秀要么生锈
  • 相关阅读:
    按位与、或、非、异或总结
    Linux 挂载命令
    Linux 文件系统常用命令
    Linux 系统命令sudo权限
    Linux 文件系统属性chattr权限
    Linux 文件特殊权限-Sticky BIT
    Linux 文件特殊权限-SetGID
    Linux 文件特殊权限-SetUID
    Linux 递归acl权限和默认acl权限
    Linux 最大有效权限与删除ACL
  • 原文地址:https://www.cnblogs.com/Superwalker/p/7851436.html
Copyright © 2011-2022 走看看