[贪心] 耍杂技的牛(公式推导+贪心)

0. 前言

我个人认为,贪心问题和数学式子密切相关。先有贪心思路,再简单写出式子,重点在于式子的正确性证明。大多都是不等式的方式证明等式,而不等式又牵扯到了各类的均值、调和、绝对值不等式等等,相当有意思 😦

1. 公式推导+贪心

125. 耍杂技的牛

在这里插入图片描述
样例模拟:

危险系数:上面所有牛的重量之和减去自己的强壮值
  重量w		强壮值s  		危险系数
   3		  3			0-3=-3
   2		  5			3-5=-2
  10		  3			3+2-3=2		最大危险系数小,为2

贪心思路:

  • 按照 w i + s i w_i+s_i wi+si 从小到大的顺序排,最大的危险系数一定是最小的

证明:

  • 从两个方面证明,贪心答案等于最优解:
    • 贪心得到的答案一定大于等于最优解。因为最优解是所有方案的最小值,则贪心答案一定大于等于最优解
    • 贪心得到的答案一定小于等于最优解
      • 如果最优解不是按照 w i + s i w_i+s_i wi+si 从小到大排序的。那么一定存在相邻两头牛,满足 w i + s i > w i + 1 + s i + 1 w_i+s_i > w_{i+1}+s_{i+1} wi+si>wi+1+si+1
        						第 i 头牛						第i+1头牛
        交换前危险系数		w1+w2+...+w(i-1)-si			w1+w2+...+w(i-1)+wi-s(i+1)
        交换后危险系数		w1+w2+...+w(i-1)-s(i+1)		w1+w2+...+w(i-1)+w(i+1)-si
        
        由于都有	w1+w2+...+w(i-1),则可以去掉,则为
        交换前危险系数		-si							wi-s(i+1)
        交换后危险系数		-s(i+1)						w(i+1)-si
        
        给这四个数,统一加上 si+s(i+1),能好理解些
        交换前危险系数		s(i+1)						wi+si
        交换后危险系数		si							w(i+1)+s(i+1)
        
        由于每个 wi、si 都是严格大于等于1的,那么 wi+si > si 恒成立
        已知 w(i+1)+s(i+1) < wi+si
        那么交换后 si、w(i+1)+s(i+1) 均严格小于 wi+si,故也严格小于交换前的 s(i+1)、wi+si 的最大值
        那么说明,交换后其余牛位置不变,交换前后会使这两个牛的危险系数最大值变小
        
        故,若最优解出现了逆序关系,则可以交换,且交换后最优解不会变大,直至变成有序的序列,最后等于贪心序列
        那么在这个过程中,由于最优解交换后不会变大,可能不变和变小,交换重点为贪心序列,则贪心答案一定小于等于最优解
        
        故,证得 贪心答案等于最优解
        

本题还是很难的贪心问题,但是很经典…貌似是 2012 年 NOIP 提高组的题目。

代码:

#include <iostream>
#include <algorithm>

using namespace std;

typedef pair<int, int> PII;

const int N = 5e5+5;

int n;
PII cow[N];

int main() {
    cin >> n;
    for (int i = 0; i < n; ++i) {
        int w, s;
        cin >> w >> s;
        cow[i] = {w + s, s};
    }
    
    sort(cow, cow + n);
    
    int res = -2e9, sum = 0;
    for (int i = 0; i < n; ++i) {
        int w = cow[i].first - cow[i].second, s = cow[i].second; 
        res = max(res, sum - s);
        sum += w;
    }
    
    cout << res << endl;
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值