当前位置:   article > 正文

贪心-耍杂技的牛

贪心-耍杂技的牛

问题描述

农民约翰的 N头奶牛(编号为 1…N)计划逃跑并加入马戏团,为此它们决定练习表演杂技。
奶牛们不是非常有创意,只提出了一个杂技表演:
叠罗汉,表演时,奶牛们站在彼此的身上,形成一个高高的垂直堆叠
奶牛们正在试图找到自己在这个堆叠中应该所处的位置顺序。
这 N头奶牛中的每一头都有着自己的重量 Wi以及自己的强壮程度 Si
一头牛支撑不住的可能性取决于它头上所有牛的总重量(不包括它自己)减去它的身体强壮程度的值,现在称该数值为风险值,风险值越大,这只牛撑不住的可能性越高。
您的任务是确定奶牛的排序,使得所有奶牛的风险值中的最大值尽可能的小。

输入格式

第一行输入整数 N,表示奶牛数量。
接下来 N行,每行输入两个整数,表示牛的重量和强壮程度,第 i行表示第 i头牛的重量 Wi以及它的强壮程度 Si

输出格式

输出一个整数,表示最大风险值的最小可能值。

数据范围

1≤N≤50000,1≤Wi≤10,000,1≤Si≤1,000,000,000

输入样例

3
10 3
2 5
3 3
  • 1
  • 2
  • 3
  • 4

输出样例

2
  • 1

问题分析

通过题目,我们知道每头牛的危险值=它上面牛的重量之和-自身的强壮值。
要使每头牛的危险值最小,根据贪心思想:

  • 自身w值越大应该放到底部(即减小上面式子中的被减数)
  • 自身s值越大应该放到底部(即增大上述中的减数);
    所以每头牛的(w+s)值越大应该排在后面,即升序排序。

数学分析证明:
在这里插入图片描述
交换之前其他牛的危险值不变

  • i之前的牛并不涉及牛i与i+1的重量值。
  • i+1之后的牛只涉及到牛i与i+1重量值的和

所以交换分析前后这两头牛中最大的危险值即可。
将上述式子进行化简,得到下面的式子
在这里插入图片描述
由于s,w都是整数,wi-si+1>-si+1,wi+1-si>-si;比较wi-si+1,wi+1-si即可

  • 当wi-si+1>=wi+1-si,即wi+si>=wi+1+si+1时,交换后更优
  • 当wi-si+1<wi+1-si,即wi+si<wi+1+si+1时,交换前更优

所以得到做法:按每头牛的w+s进行排序。
然后根据题意算出每头牛的危险值记录其中的最大值即可。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=50010;
typedef pair<int,int> PII;
PII cow[N]; // 定义一个pair类型的数组,用于存储牛的重量和能力值
int n; // 牛的数量
int main()
{
    cin>>n; // 输入牛的数量
    for(int i=0;i<n;i++)
    {
        int w,s; // w表示牛的重量,s表示牛的能力值
        cin>>w>>s; // 输入每头牛的重量和能力值
        cow[i]={w+s,w}; // 将每头牛的重量和能力值存入数组中
    }
    sort(cow,cow+n); // 对数组进行排序,按照重量和能力值的和从小到大排序
    int res=-2e9,sum=0; // res表示结果,sum表示当前牛的总重量
    for(int i=0;i<n;i++)
    {
        int s=cow[i].first-cow[i].second,w=cow[i].second; // 计算当前牛的能力值和重量
        res=max(res,sum-s); // 更新结果
        sum+=w; // 更新总重量
    }
    cout<<res<<endl; // 输出结果
    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/540838
推荐阅读
相关标签
  

闽ICP备14008679号