CF976E Well played!


思路:

參考了http://codeforces.com/blog/entry/59195

可以證明在最優解中所有的第一種操作都是施加同一個物種上的。那么首先按照hp - dmg對所有物種降序排序,貪心選擇前b個進行第二種(賦值)操作。然后枚舉所有物種,選擇一個進行第一種操作,在所有情況中取最大值。

在選擇一個物種進行第一種操作的時候,不要按照(hp << a) - dmg貪心,反例:

3 1 2

20 10

5 1

25 25

實現:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef pair<ll, ll> pll;
 5 
 6 const int MAXN = 200005;
 7 const ll INF = 0x3f3f3f3f3f3f3f3f;
 8 
 9 vector<pll> v;
10 
11 bool cmp(pll & x, pll & y)
12 {
13     return x.first - x.second > y.first - y.second;
14 }
15 
16 int main()
17 {
18     int n, a, b;
19     while (cin >> n >> a >> b)
20     {    
21         v.resize(n);
22         ll ans = 0;
23         for (int i = 0; i < n; i++) 
24         {
25             cin >> v[i].first >> v[i].second;
26             ans += v[i].second;
27         }
28         if (!b) { cout << ans << endl; continue; }
29         sort(v.begin(), v.end(), cmp);
30         int i = 0;
31         for ( ; i < v.size(); i++)
32         {
33             if (v[i].first <= v[i].second) break;
34         }
35         int pos = min(n, min(i, b));
36         ans = 0;
37         for (int i = 0; i < pos; i++) ans += v[i].first;
38         for (int i = pos; i < n; i++) ans += v[i].second;
39         ll maxn = ans;
40         for (int i = 0; i < n; i++)
41         {
42             if (i < pos)
43             {
44                 ll tmp = ans - v[i].first + (v[i].first << a);
45                 if (tmp > maxn) maxn = tmp;
46             }
47             else
48             {
49                 ll tmp = ans - v[i].second + (v[i].first << a);
50                 if (pos && pos == b) tmp += - v[pos - 1].first + v[pos - 1].second;
51                 if (tmp > maxn) maxn = tmp;
52             }
53         }
54         cout << maxn << endl;
55     }
56     return 0;
57 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM