• Greedy:Cow Acrobats(POJ 3045)


               

                    牛杂技团

      题目大意:一群牛想逃跑,他们想通过搭牛梯来通过,现在定义risk(注意可是负的)为当前牛上面的牛的总重量-当前牛的strength,问应该怎么排列才能使risk最小?

      说实话这道题我一开始给书上的二分法给弄懵了,后来看了一下题解发现根本不是这么一回事,其实就是个简单的贪心法而已。

      这题怎么贪心呢?就是按w+s从小到大排序就好了,证明一下:

      1.先证明如果不满足w+s的序列性,无论谁在谁的上面,都会违反题设:(设A在B的上面)

        如果 A.s+A.w<B.s+B.w

        则如果B.s<m+A.w

        则如果B在A的上面A.s<B.s+B.w-A.w=B.w+m

        得证

      2.再证明一下如果采用排序的确能让risk的最大值最小。

        如果 A.s+A.w<B.s+B.w

        ①A在B的上面

        riskA1=m-A.s  riskB1=m+A.w-B.s

        ②B在A的上面

        riskB2=m-B.s  riskA2=m+B.w-A.s

        所以riskA2>riskA1

          另外riskB1-riskA2=A.w+A.s-B.w-B.s<0  所以riskA2>riskB1>riskB2

        则违反后risk会产生一个比三个risk更大的数,不符合题意

        参考http://poj.org/showmessage?message_id=341726

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <functional>
     4 
     5 using namespace std;
     6 typedef long long LL_INT;
     7 
     8 typedef struct _cows
     9 {
    10     LL_INT strength;
    11     LL_INT weight;
    12     bool operator<(const  _cows &x) const
    13     {
    14         return strength + weight > x.weight + x.strength;
    15     }
    16 }Cows;
    17 
    18 static Cows cows_set[50001];
    19 void Search(const int, LL_INT);
    20 bool judge(const LL_INT, const int,const LL_INT);
    21 
    22 int main(void)
    23 {
    24     int sum_cows;
    25     LL_INT sum_w;
    26     
    27     while (~scanf("%d", &sum_cows))
    28     {
    29         sum_w = 0;
    30         for (int i = 0; i < sum_cows; i++)
    31         {
    32             scanf("%lld%lld", &cows_set[i].weight, &cows_set[i].strength);
    33             sum_w += cows_set[i].weight;
    34         }
    35         sort(cows_set, cows_set + sum_cows);
    36         Search(sum_cows,sum_w);
    37     }
    38     return 0; 
    39 }
    40 
    41 void Search(const int sum_cows, LL_INT sum_w)
    42 {
    43     LL_INT ans = -1000000001;
    44 
    45     for (int i = 0; i < sum_cows; i++)
    46     {
    47         sum_w -= cows_set[i].weight;
    48         ans = max(ans, sum_w - cows_set[i].strength);
    49     }
    50     cout << ans << endl;
    51 }

    其实这题的思想和Protecting Flowers那题有点像,都是只看两个元素之间的两个量之间的练联系,而不只是单单的一个量

  • 相关阅读:
    Android高斯模糊技术,实现毛玻璃效果(转)
    设计模式笔记之六:生产消费者模式
    设计模式笔记之五:观察者模式
    设计模式笔记之四:MVP+Retrofit+RxJava组合使用
    设计模式笔记之三:Android DataBinding库(MVVM设计模式)
    Eclipse Code Recommenders 自动补全(联想)神器
    java根据freeMark模板生成内容
    通过java反射机制,获取对象的属性和值(包括所有继承的父类)
    win7下自动更新svn目录
    jdk11 eclipse下开启ZGC
  • 原文地址:https://www.cnblogs.com/Philip-Tell-Truth/p/5132093.html
Copyright © 2020-2023  润新知