有n
nn頭奶牛,編號1∼n
1\sim n
1∼n,每個奶牛有兩個屬性,自己的重量w
iw_i
wi和其強壯程度s
is_i
si。它們要表演疊羅漢,乙個疊在另乙個上面,每個奶牛的風險值定義為其上方的所有奶牛的重量之和減去其自己的強壯程度。問如何安排疊羅漢次序可以使得風險值最大的那個奶牛的風險值最小。
輸入格式:
第一行輸入整數n
nn,表示奶牛數量。接下來n
nn行,每行輸入兩個整數,表示牛的重量和強壯程度,第i
ii行表示第i
ii頭牛的重量w
iw_i
wi以及它的強壯程度s
is_i
si。
輸出格式:
輸出乙個整數,表示最大風險值的最小可能值。
資料範圍:
1 ≤n
≤50000
1\le n\le 50000
1≤n≤50
0001≤w
i≤
10000
1\le w_i\le 10000
1≤wi≤
100001≤
si≤1
09
1\le s_i\le 10^9
1≤si≤
109可以將奶牛按照wi+
si
w_i+s_i
wi+si
從小到大排序,小的在上,大的在下,進行疊羅漢。此時最大風險值最小。
演算法正確性證明:
設最優解不是上述所說的,那麼一定存在兩頭相鄰的奶牛,滿足wi+
1+si
+1
+s
iw_+s_wi
+1+
si+1
+si
,那麼位於位置i
ii的奶牛的風險值是w1+
...+
wi−1
−s
iw_1+...+w_-s_i
w1+..
.+wi
−1−
si,而位於位置i+1
i+1i+
1的奶牛的風險值是w1+
...+
wi−s
i+
1w_1+...+w_i-s_
w1+..
.+wi
−si
+1;如果交換這兩頭奶牛,那麼這時位於位置i
ii的奶牛的風險值是w1+
...+
wi−1
−si+
1w_1+...+w_-s_
w1+..
.+wi
−1−
si+1
,位於位置i+1
i+1i+
1的奶牛的風險值是w1+
...+
wi−1
+wi+
1−si
w_1+...+w_+w_-s_i
w1+..
.+wi
−1+
wi+1
−si
,我們只需比較max
\max\\}
max和max
\max\,w_-s_i\}
max,由於wi+
1+si
+1
+s
iw_+s_wi
+1+
si+1
+si
,所以wi+
1−si
−si+
1w_-s_iwi
+1−
si−si
+1,又w
i>
0w_i>0
wi>
0,所以−si
+1
−si+
1-s_−s
i+1
−si
+1,所以max
−si+
1≤
max
\max\,w_-s_i\}
max−si
+1≤
max,可以看出換位子之後,最大風險值會變小或者不變。既然當前解就是最優解,所以換位子之後最大風險值應當是不變的,那我們重複這樣的操作,不停交換這樣的逆序對,直到從上到下是按照wi+
si
w_i+s_i
wi+si
從小到大排列為止(這是氣泡排序,是可以做到的),說明這樣排列也是最優解,所以演算法正確。
**如下:
時間複雜度o(n#include
#include
using
namespace std;
const
int n =
50010
;pair<
int,
int> a[n]
;// 重新定義pair的比較函式(定義小於)
bool
compare
(const pair<
int,
int>
& p1,
const pair<
int,
int>
& p2)
intmain()
cout << res << endl;
return0;
}
logn)
o(n\log n)
o(nlogn)
,空間o(1
)o(1)
o(1)
。
Acwing 125 耍雜技的牛
農民約翰的n頭奶牛 編號為1.n 計畫逃跑並加入馬戲團,為此它們決定練習表演雜技。奶牛們不是非常有創意,只提出了乙個雜技表演 疊羅漢,表演時,奶牛們站在彼此的身上,形成乙個高高的垂直堆疊。奶牛們正在試圖找到自己在這個堆疊中應該所處的位置順序。這n頭奶牛中的每一頭都有著自己的重量wi以及自己的強壯程度...
AcWing 125 耍雜技的牛
這是一道不簡單的貪心,難度還是有的,老師的分析方法真的很不錯啊,老師講課 這個牛是垂直擺放的,首先我們對兩個量進行乙個比較 我們先假設後面的是最大值,那我們對兩頭牛,只要滿足wi si include include using namespace std typedef pair int,int ...
AcWing 125 耍雜技的牛 貪心
題目鏈結 農民約翰的n頭奶牛 編號為1 n 計畫逃跑並加入馬戲團,為此它們決定練習表演雜技。奶牛們不是非常有創意,只提出了乙個雜技表演 疊羅漢,表演時,奶牛們站在彼此的身上,形成乙個高高的垂直堆疊。奶牛們正在試圖找到自己在這個堆疊中應該所處的位置順序。這n頭奶牛中的每一頭都有著自己的重量wi以及自己...