農民約翰的\(n\)頭奶牛(編號為\(1..n\))計畫逃跑並加入馬戲團,為此它們決定練習表演雜技。對相鄰的兩頭牛進行分析,分別寫出交換前和交換後兩頭牛的危險值奶牛們不是非常有創意,只提出了乙個雜技表演:
疊羅漢,表演時,奶牛們站在彼此的身上,形成乙個高高的垂直堆疊。
奶牛們正在試圖找到自己在這個堆疊中應該所處的位置順序。
這n頭奶牛中的每一頭都有著自己的重量wi以及自己的強壯程度\(s_i\)。
一頭牛支撐不住的可能性取決於它頭上所有牛的總重量(不包括它自己)減去它的身體強壯程度的值,現在稱該數值為風險值,風險值越大,這只牛撐不住的可能性越高。
您的任務是確定奶牛的排序,使得所有奶牛的風險值中的最大值盡可能的小。
交換前 :牛\(i\)在牛\(i+1\)上方
牛\(i\):\(w_1 + ... + w_ - s_i\)
牛\(i+1\):\(w_1 + ... + w_i - s_\)
交換後:
牛\(i\):\(w_1 + ... + w_ + w_ - s_i\)
牛\(i+1\):\(w_1 + ... + w_ - s_\)
我們想要**的只是這些資料的大小關係,所以可以去掉相同的部分
交換前 :牛\(i\)在牛\(i+1\)上方
牛\(i\):\(-s_i\)
牛\(i+1\):\(w_i - s_\)
交換後:
牛\(i\):\(w_ - s_i\)
牛\(i+1\):\(-s_\)
可以發現,\(w_i+1 - s_i > -s_i, w_i - s_ > -s_\)
所以想要判斷交換前和交換後最大值的關係,只需要** \(w_i - s_\) 和 \(w_ - s_i\)的關係
因為假設 \(w_i - s_ > w_ - s_i\),說明交換前兩頭牛之間的最大值是\(w_i - s_\)且交換前的最大值一定大於交換後的最大值,雖然無法判斷交換後的最大值是哪個
同理,根據 \(w_i - s_ < w_ - s_i\) 也一定可以判斷出交換後的最大值一定大於交換前的最大值
交換前的最大值 > 交換後的最大值說明我們的交換是有意義的,此時滿足 \(w_i - s_ > w_ - s_i\),變形可得 \(w_i + s_i > w_ + s_\),
就是說當前乙個牛的\(w+s\)比後面的更大時,交換就可以使答案更優,所以我們只需要根據\(w+s\)從小到大排序,然後遍歷一遍求出最大值即可,此時的最大值就是所有最大值中最小的
上面的解法能夠實現具有乙個很重要的條件:任意交換相鄰兩頭牛的位置對除這兩頭牛外的其他牛並沒有影響
#include #include #include #include using namespace std;
typedef pairpii;
const int n = 50010;
int n;
vectorcows;
int main()
); }
sort(cows.begin(), cows.end(), (pii a, pii b) );
int sum = 0, res = int_min;
for (int i = 0; i < n; ++ i)
cout << res << endl;
}
耍雜技的牛
傳送門 題意 農民約翰的n頭奶牛 編號為1 n 計畫逃跑並加入馬戲團,為此它們決定練習表演雜技。奶牛們不是非常有創意,只提出了乙個雜技表演 疊羅漢,表演時,奶牛們站在彼此的身上,形成乙個高高的垂直堆疊。奶牛們正在試圖找到自己在這個堆疊中應該所處的位置順序。這n頭奶牛中的每一頭都有著自己的重量wi以及...
耍雜技的牛
農民約翰的n nn頭奶牛 編號為1.n1.n 1.n 計畫逃跑並加入馬戲團,為此它們決定練習表演雜技。奶牛們不是非常有創意,只提出了乙個雜技表演 疊羅漢,表演時,奶牛們站在彼此的身上,形成乙個高高的垂直堆疊。奶牛們正在試圖找到自己在這個堆疊中應該所處的位置順序。這n nn頭奶牛中的每一頭都有著自己的...
125 耍雜技的牛
結論 證明 第乙個不用證明,很明顯 第二個 假設wi si w i 1 s i 1 由於wi si w i 1 s i 1 wi si si 所以交換後 兩頭牛的風險的最大值一定是小於交換前兩頭牛的風險的最大值的!那麼總體的風險的最大值就不可能增加,只可能不變或減小。所以得證。所以我們就按wi si...