算法1
(贪心)
题目要求牛的最大伤害值最小,那么我们使每头牛的伤害值最小,在其中找最大值作为答案
如何使得每头牛的伤害值最小?
(1) 自身w值越大应该放到底部,使得被减数减小
(2) 自身s值越大应该放到底部,使得减数变大
综上,w + s 从小到大排序,最大的危险系数一定是最小的。
贪心算法的证明过程:
贪心所得到的解 == 最优解
(1)贪心所得到的解 >= 最优解
由于最终答案所有可行方案中的最大值,而用贪心得到的解是一个可行解,因此最优解一定大于贪心得到的解
(2)贪心得到的解 <= 最优解
假设最优解不是 w + s从小到达排序的,那么必然存在相邻两头牛,使得 $w_i$ + $s_i$ > $w_i+1$ + $si+1$
交换前的伤害值:
第i个位置上的牛:$ w_1 + w_2 + ... + w_~i-1 - s_i $
第i+1个位置上的牛:$ w_1 + w_2 + ... + w_i-1 + w_i - s_~ i + 1$
交换后的伤害值:
第i个位置上的牛:$ w_1 + w_2 + ... + w_~i-1 - s_~i+1 $
第i+1个位置上的牛:$ w_1 + w_2 + ... + w_~i-1 + w_i+1 - s_i$
由于交换前和交换后的式子当中都有$w_1 + w_2 + ... + w_i-1$,因此我们可以同时去掉他
再加上$s_i + s_i+1$
去掉w[1] + ...+w[i-1]之后:
第i个位置上的牛 第i+1个位置上的牛
交换前: -s[i] w[i] - s[i + 1]
交换后: -s[i + 1] w[i+1] - s[i]
----------
加上(s[i] + s[i+1])之后:
第i个位置上的牛 第i+1个位置上的牛
交换前: s[i+1] w[i]+s[i]
交换后: s[i] w[i+1]+s[i+1]
从上面的式子当中可以看出,$w_i + s_i > s_i$
又我们再前面假设当中 $w_i$ + $s_i$ > $w_i+1$ + $si+1$
因此,我们可以得出 (交换前)$s_i+1 + w_i + s_i $ 大于(交换后) $s_i + w_i+1 + s_i+1$
也就是说,交换后的值,严格变小了, 此时我们可以证明出贪心得到的值 <= 最优值
证毕!
C++ 代码
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
const int N = 50010;
int n;
PII cow[N];
int main(){
scanf("%d",&n);
for(int i = 0 ; i < n; i++){
int w,s;
scanf("%d%d",&w,&s);
cow[i] = {w + s, w};
}
//按照 w + s 从小到大进行排序
sort(cow, cow + n);
int ans = -2e9, sum = 0; //sum表示当前我头上的牛的重量
for(int i = 0; i < n; i ++){
int w = cow[i].second, s = cow[i].first - w; //当前牛的强壮值
ans = max(ans, sum - s); //我头上的牛的总重量 - 我的强壮值
sum += w;
}
printf("%d",ans);
return 0;
}
标签:...,杂技,cow,int,sum,交换,125,AcWing,贪心 From: https://www.cnblogs.com/ltphy-/p/18419425