耍杂技的牛:
我们先分析每头牛的危险值 = 他前面牛的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<wi+1−si,即 wi+si<wi+1+si+1时, 交换前更优
所以得到做法: 按每头牛的 w + s 进行排序, 当存在逆序时就进行交换(即升序排序),
然后根据题意算出每头牛的危险值记录其中的最大值即可
#include <iostream>
#include <algorithm>using namespace std;typedef pair<int,int>PII;//把w+s和w一组,用于后面排序,公式用的到w+sconst int N=50010;int n;
int w[N],s[N];//w是i的重量,s是i的强壮程度
PII cow[N];//每头牛的w+s和wint 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;
}