Summary
比赛中仅仅做出3道水题。
卡E。E一直想不出。曾有猜测“所有1st type spells全部用于一个creature”,但无法证明,也不敢下定论。没想到这就是正解。
题解
E. Well played!
题目大意
有n个物品,每个物品有两个值hp和dmg. 现有a个第一类道具和b个第二类道具。第一类道具可以使某个物品的hp翻倍,第二类道具可以将某个物品的hp赋值给dmg.
问使用了这些道具后,所有物品dmg和的最大值。
数据范围: $1\leq n\leq2\cdot10^5,0\leq b\leq2\cdot10^5,0\leq a\leq 20$
solution
下面先证明,最优解一定是全部第一类道具用于同一个物品。分别用x和y表示物品的hp和dmg.
那么如果两个物品同时用了第一类道具,分别用了$a_1$和$a_2$个,它们的总dmg就是$d_1 = {x_1}2^{a_1}+{x_2}2^{a_2}$.
如果将第一类道具全部用于第1个物品,总dmg为$d_2={x_1}2^{a_1+a_2}+\max(x_2, y_2)$
假设d1更优,则有$${x_1}2^{a_1}+{x_2}2^{a_2} > {x_1}2^{a_1+a_2}+\max(x_2, y_2)$$
移项,有$${x_1}2^{a_1}(2^{a_2}-1) < {x_2}2^{a_2} - \max(x_2, y_2)$$
考虑到$\max(x_2, y_2) \geq x_2$,则有$${x_1}2^{a_1}(2^{a_2}-1) < {x_2}(2^{a_2}-1)$$
即$${x_1}2^{a_1}< {x_2}$$
同理,为了让$d_1$比第一类道具全部用于第2个物品的情况更优,有
$${x_2}2^{a_2}< {x_1}$$
两个不等式矛盾,证毕。
这样一来,就可以O(n)枚举每个物品使用第一类道具的情况。
source code
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5+10; struct P { ll h, d; bool used; P(ll h = 0, ll d = 0): h(h), d(d), used(false){} bool operator < (const P &b) { return h - d > b.h - b.d; } }a[N]; void Maxi(ll &a, ll b) { if (b > a) a = b; } int main() { int n, A, b; scanf("%d%d%d", &n, &A, &b); ll k = 1; for (int i = 0; i < A; i++) k <<= 1; for (int i = 0; i < n; i++) { int h,d; scanf("%d%d", &h, &d); a[i] = P(h, d); } sort(a, a + n); ll tot = 0, cnt = 0; for (int i = 0; i < n; i++) { if (a[i].h > a[i].d && cnt < b) { ++cnt; tot += a[i].h; a[i].used = true; } else { tot += a[i].d; } } ll ans = tot; for (int i = 0; i < n; i++) { ll h = a[i].h * k; if (h <= a[i].d) continue; if (a[i].used) { Maxi(ans, tot - a[i].h + h); } else { ll temp = tot - a[i].d + h; if (cnt == b) { temp = temp - a[b - 1].h + a[b - 1].d; } Maxi(ans, temp); } } printf("%lld\n", ans); }
|
Last updated: