贪心:推公式

 耍杂技的牛:

 我们先分析每头牛的危险值 = 他前面牛的w(重量值)和 - 自身的s(强壮值),要使每头牛的危险值最小,这显然是与w 和 s同时相关,所以先想出一种做法按 每头牛的w + s进行升序排序(题见多了可能就会有这种题感)。接下来进行数学分析证明: 

i是从上往下数:

其他牛的危险值显然不变,所以分析交换前后这两头牛中最大的危险值即可。

由于s, w都是正数,wi−si+1>−si+1 , wi+1−si>−si

对于同一头牛i+1,比较wi−si+1, wi+1−si 即可

当wi−si+1>=wi+1−si,即 wi+si>=wi+1+si+1时, 交换后更优

当wi−si+1时, 交换前更优

所以得到做法: 按每头牛的 w + s 进行排序, 当存在逆序时就进行交换(即升序排序),
然后根据题意算出每头牛的危险值记录其中的最大值即可

#include 
#include 

using namespace std;

typedef pairPII;//把w+s和w一组,用于后面排序,公式用的到w+s

const int N=50010;

int n;
int w[N],s[N];//w是i的重量,s是i的强壮程度
PII cow[N];//每头牛的w+s和w

int main()
{
    int n;
    scanf("%d",&n);
    for(int i = 0; i < n; i ++ )
    {
        int w,s;
        scanf("%d%d", &w, &s);
        cow[i]={w+s,w};
    }

    sort(cow,cow+n);//用w+s升序,可以计算最大危险值的最小可能值
    
    int res=-2e9,sum=0;//答案先赋负无穷,sum表示每头牛上面的重量之和
    
    for(int i = 0; i < n; i ++ )//计算最大危险值
    {
        int w=cow[i].second,s=cow[i].first-w;       
        res=max(res,sum-s);//sum-s计算危险系数
        sum+=w;//加上这头牛的重量
    }
    printf("%d\n",res);
    return 0;
}

你可能感兴趣的:(算法基础,算法)