农民约翰的N头奶牛(编号为$1..N$)计划逃跑并加入马戏团,为此它们决定练习表演杂技。

奶牛们不是非常有创意,只提出了一个杂技表演:

叠罗汉,表演时,奶牛们站在彼此的身上,形成一个高高的垂直堆叠。

奶牛们正在试图找到自己在这个堆叠中应该所处的位置顺序。

这$N$头奶牛中的每一头都有着自己的重量Wi以及自己的强壮程度$S_i$。

一头牛只撑不住的可能性取决于它头上所有牛的总重量(不包括它自己)减去它的身体强壮程度的值,现在称该数值为风险值,风险值越大,这只牛撑不住的可能性越高。

您的任务是确定奶牛的排序,使得所有奶牛的风险值中的最大值尽可能的小

输入格式

第一行输入整数$N$,表示奶牛数量。

接下来$N$行,每行输入两个整数,表示牛的重量和强壮程度,第$i$行表示第$i$头牛的重量Wi以及它的强壮程度$S_i$。

输出格式

输出一个整数,表示最大风险值的最小可能值。

数据范围

$1≤N≤50000$,
$1≤Wi≤10,000$,
$1≤Si≤1,000,000,000$

输入样例:

1
2
3
4
3
10 3
2 5
3 3

输出样例:

1
2

重点是推公式,下面给出分析方法:

对于第$i$头牛,它的风险程度为$\sum_0^{i-1}w_i-s_i$,第$i+1$头牛的风险程度为$\sum_0^{i}w_i-s_{i+1}$。

如果把这两头相邻的牛交换,则风险程度分别为$\sum_0^{i-1}w_i-s_{i+1}$和$\sum_0^{i-1}w_i+w_{i+1}-s_i$。

在交换前,$i+1$头牛的风险程度较大。交换后,$i$头牛的风险程度较大。

当$\sum_0^iw_i-s_{i+1}<\sum_0^{i-1}w_i+w_{i+1}-s_{i}$时,有$w_i+s_i<w_{i+1}+s_{i+1}$。

可以知道,可以是用$w+s$进行从小到大排序。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <bits/stdc++.h>
using namespace std;
int n;
struct cow {
int w, s;
bool operator< (const cow& C) const {
return w + s < C.w + C.s;
}
};

int main() {
scanf("%d", &n);
vector<cow> v;
for(int i = 0; i < n; ++i) {
int w, s;
scanf("%d%d", &w, &s);
struct cow c{w, s};
v.push_back(c);
}
sort(v.begin(), v.end());
int res = -2e9;
int w_sum = 0;
for(auto t : v) {
res = max(res, w_sum - t.s);
w_sum += t.w;
}
printf("%d", res);
return 0;
}