zoukankan      html  css  js  c++  java
  • poj 3045

    /*
        题意:
            给定n,然后是n头牛,每头牛有一个重量w,力量s
            要求把n头牛一个叠在一个头上,类似叠罗汉
            对于一个叠罗汉的序列,每头牛的risk是它顶上的牛的重量之和减去它的s
            对于序列的最大的risk就是这个序列的risk
            问如何确定一种序列使得risk最小
        解析:
            首先要想到,对于相邻的两头牛,交换它们的位置,仅仅会影响他们两个的risk值
            然后,对于最优系列的相邻的两头牛
            w1 s1
            w2 s2
            最顶上的那头的顶上的牛的质量和为sum
            那么第一头牛的risk就是 sum - s1   r1
            第二头的为sum + w1 - s2           r2
    
            假如交换位置之后:
                sum - s2                      r3
                sum + w2 - s1                 r4
            有:max(r1,r2) < max(r3,r4)——r1..r4分别对应四个risk
    
            那么,有四种假设:
                r1 < r3
                r1 < r4
                r2 < r3
                r2 < r4
            当然这四个假设,每一个都还隐含了两个不等式,在这里先不写出来
            因为明显有 r1 < r4 r2 > r3
            所以,只剩下:
                1.r1 < r3 —— r1 > r2 && r3 > r4
                2.r2 < r4 —— r2 > r1 && r4 > r3
    
            对于1:
                s2 - s1 > w1 && s1 - s2 > w2,因为w1,w2都大于0,所以不符合。
            所以只剩下2
                得到:w1 + s1 < w2 + s2
            综上,得出w+s最大的必定在最底下,按照w+s排序得到的就是最优序列。
    
    
            顺便,要注意一下,risk是可以为负数的,所以初始化的时候不可以为0。
    */
    
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #define range(i,a,b) for (int i=a;i<=b;i++)
    
    const int maxn = 50000;
    
    typedef long long ll;
    
    using namespace std;
    
    struct Data
    {
        ll w,s;
        friend bool operator < (const Data &a,const Data &b)
        {
            return a.w+a.s < b.w + b.s;
        }
    };
    
    ll n;
    Data dat[maxn+1];
    
    void input(ll &a)
    {
        scanf("%I64d",&a);
    }
    
    int main()
    {
        input(n);
        range(c,1,n)
        {
            input(dat[c].w);
            input(dat[c].s);
        }
    
        sort(dat+1,dat+1+n);
    
        ll sum(0);
        ll risk=-(1<<29);
        //初始化状态为0的话,就会WA!
    
        range(i,1,n)
        {
            risk = sum - dat[i].s > risk ? sum - dat[i].s : risk;
            sum += dat[i].w;
        }
    
        cout<<risk<<endl;
    
        return 0;
    }
  • 相关阅读:
    海量文件查重SimHash和Minhash
    刷题中熟悉Shell命令之Tenth Line和Transpose File [leetcode]
    C# 开发XML Web Service与Java开发WebService
    Sketchup+ArcGIS三维建模与管理
    入门-Arcmap网络分析示例
    建议入门-用ArcMap进行空间查询与空间连接
    (转载)Htmlparser Filter 简要归纳
    (转载)java常见的ClassNotFoundException
    C# WinForm程序向datagridview里添加数据
    oracle数据库的简单操作
  • 原文地址:https://www.cnblogs.com/dandi/p/4068787.html
Copyright © 2011-2022 走看看