洛谷 题解 P1842 【奶牛玩杂技】
本蒟蒻又双叒叕被爆踩辣!
Solution:
我们先看数据,50000,那么O(n)或者O(n log(n))是可以过的,非严格O(n * sqrt(n))要卡卡常,说不定也可以过。
那么什么算法可以在解决这道题的同时来达到期望复杂度嘞?
你的任务就是帮助奶牛们找出一个摞在一起的顺序,使得总压扁指数最小。
看到这句是不是感觉明白了什么?
是的,很明显就是贪心!期望复杂度O(n);
那么贪心策略是什么?
因为我们要求总压扁指数最小,那么我们先看看总压扁指数是如何求的?
它是与奶牛的体重有关?
还是与奶牛的力量有个?
对于任意的牛,她的压扁指数等于摞在她上面的所有奶牛的总重(当然不包括她自己)减去它的力量
看到这句话是不是都懂了,它与奶牛的体重以及力量都有关!
而且,因为我们要越高的奶牛的体重越小且力量越小。
又因为,s和w直接的转化比率是1:1(就是一单位的体重可以用一单位的力量来支撑
那么我们的贪心策略就是按照s + w来排序;
上面是对问题的感性理解,
接下来,我来讲一讲如何证明为什么要越高的奶牛的体重越小且力量越小(显然啊:
假设x, y为相邻的奶牛,
且 Wx + Sx < Wy + Sy;
那么 Wx - Sy < Wy-Sx;
那么显然是右边的情况更优,窝们就应该把x放在上面,y在下面。
那么既然这里已经想通了,就很简单辣!
Code:
#include<bits/stdc++.h>
using namespace std;
#define maxn 50010
#define inf 1000000000
#define Rep(x, a, b) for(int x = a; x <= b; ++ x)
#define Dep(x, a, b) for(int x = a; x >= b; -- x)
struct node{
int w, s, sum;
}e[maxn];//w,s如题,sum是w+s;
int n, ans = -inf, now;//ans要赋极小值。
bool cmp(node x, node y){
return x.sum < y.sum;
}//按w+s排序。
int main(){
scanf("%d", &n);//输入
Rep(i, 1, n){
scanf("%d%d", &e[i].w, &e[i].s);//输入
e[i].sum = e[i].w + e[i].s;//求出结构体排序的条件
now += e[i].w;//先全部加起来,方便从倒叙求解
}
sort(e + 1, e + n + 1, cmp);//按照贪心方案,从小往大排序!
Dep(i, n, 1){//记得要倒序!
now -= e[i].w;//在减去w
ans = max(now - e[i].s, ans);//求出ans最大,此时使得总压扁指数最小
}
printf("%d", ans);//输出
return 0;
}
Ps:请看懂再抄