洛谷 题解 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:请看懂再抄