1. 程式人生 > >訓練部隊--全國模擬(三)

訓練部隊--全國模擬(三)

urn 獲得 訓練 描述 font 限制 nbsp 發生 ear

[編程題] 訓練部隊 時間限制:1秒 空間限制:32768K 小牛牛是牛牛王國的將軍,為了訓練出精銳的部隊,他會對新兵進行訓練。部隊進入了n個新兵,每個新兵有一個戰鬥力值和潛力值,當兩個新兵進行決鬥時,總是戰鬥力值高的獲勝。獲勝的新兵的戰鬥力值就會變成對手的潛力值 + 自己的戰鬥力值 - 對手的戰鬥力值。敗者將會被淘汰。若兩者戰鬥力值一樣,則會同歸於盡,雙雙被淘汰(除了考察的那個新兵之外,其他新兵之間不會發生戰鬥) 。小牛牛想知道通過互相決鬥之後新兵中戰鬥力值+潛力值最高的一個可能達到多少,你能幫助小牛牛將軍求出來嗎? 輸入描述: 輸入包括n+1行,第一行包括一個整數n(1 ≤ n ≤ 10^5); 接下來的n行,每行兩個整數x和y(1 ≤ x,y ≤ 10^9)
輸出描述: 輸出一個整數,表示新兵中戰鬥力值+潛力值最高的一個能達到多少。 輸入例子: 2 1 2 2 1 輸出例子: 4 解題思路: 可以考慮把新兵分為兩種類型。 一種戰鬥型(戰鬥值大於潛力值的),一種潛力型(相當於打了他可以獲得潛力值),對潛力型的新兵進行戰鬥力值排序。 然後一種情況是潛力型中戰鬥值最高的牛牛去打完剩余的潛力型,因為戰鬥力值會越大越多,另一種情況考慮打完所有潛力型獲得值是固定的,那麽在攻擊型中找一個能打完所有的潛力型的牛牛,並且戰鬥力值和潛力值要最大。 實現就是用的前綴和和二分
 1 #include <bits/stdc++.h>
 2
3 using namespace std; 4 5 typedef long long LL; 6 const int maxn = 100005; 7 int n; 8 int goodn,badn; 9 LL sum[maxn],MAX[maxn]; 10 struct Node { 11 LL x,y; 12 Node() {} 13 Node (const LL &_x,const LL &_y) { x=_x; y=_y; } 14 bool operator < (const Node &t) const
{ 15 if(x ^ t.x) return x < t.x; 16 return y < t.y; 17 } 18 }good[maxn],bad[maxn]; 19 int search(int L, int R, LL x) { 20 while(L < R) { 21 int mid = (L + R + 1) >> 1; 22 if(MAX[mid] < x) L = mid; 23 else R = mid - 1; 24 } 25 return L; 26 } 27 LL solve() { 28 LL ans = 0; 29 ans = max(ans, sum[search(0, goodn - 1, good[goodn].x)] + good[goodn].x + good[goodn].y); 30 for(int i = 1; i <= badn; i++) { 31 int pos = search(0, goodn, bad[i].x); 32 ans = max(ans, sum[pos] + bad[i].x + bad[i].y); 33 } 34 return ans; 35 } 36 int main() { 37 scanf("%d", &n); 38 for(int i = 1; i <= n; i++) { 39 LL x, y; 40 scanf("%lld%lld",&x, &y); 41 if(x < y) good[++goodn] = Node(x,y); 42 else bad[++badn] = Node(x,y); 43 } 44 sort(good + 1, good + goodn + 1); 45 MAX[0] = 0; sum[0] = 0; 46 for(int i = 1; i <= goodn; i++) { 47 sum[i] = sum[i-1] + good[i].y - good[i].x; 48 MAX[i] = max(MAX[i-1], good[i].x - sum[i-1]); 49 } 50 LL ans = solve(); 51 printf("%lld\n", ans); 52 return 0; 53 }

引自:https://www.nowcoder.com/discuss/27498?type=0&order=0&pos=4&page=1

訓練部隊--全國模擬(三)