1 条题解
-
0
-
技能最多触发一次。
-
要使得触发技能时,种类数尽可能多,然后使用价值最大的牌。
-
若某种牌数量超出一张,使用它不会减少种类数。统计总共能以此法使用 张。
-
若触发技能时,该次使用的牌消耗后还有剩余,那么:
- 统计满足 的最大 ,记为 。
- 接下来最大化种类数,额外收益即种类数与 的乘积。
- 若 ,先使用 次并为该类别保留两张,第 次使用该类别牌,种类数为 。
- 若
- 若 是 的倍数,先使用 次并为该类别保留两张,接下来每次使用都将使得总类别减少 ,设使用 次,最后一次再使用该类别,那么使用次数 等于剩余类别 ,故 ,则种类数为
- 否则,可以先使用 次并为该类别保留两张, 故 ,则种类数为
-
若触发技能后,允许该次使用的牌为最后一张,则记录 的最大值,使用这种牌触发技能。额外收益的讨论类似。
-
时间复杂度是 。
#include <bits/stdc++.h> using namespace std; using ll = long long; void solve() { int n; cin >> n; vector<int> a(n), b(n); int extra_num = 0; for(int i = 0; i < n; i++) { cin >> a[i]; extra_num += a[i] - 1; extra_num = min(n, extra_num); } for(int i = 0; i < n; i++) { cin >> b[i]; } // 若希望使用后, 该牌剩余一张以上 int maxv = 0; long long ans = 0; for(int i = 0; i < n; i++) { if(a[i] > 1) maxv = max(maxv, b[i]); } // 先使用 extra 张, 再消耗 k 种类, 最后正好剩 extra + k 类 // extra + 2k = n if(extra_num || (n % 2 == 0)) { int k = (n - extra_num + 1) / 2; ans = max(ans, (n - k) * (long long) maxv); } // 若使用后, 该牌可以消失 maxv = *max_element(b.begin(), b.end()); if(extra_num || (n % 2 == 0)) { int k = max(1, (n - extra_num + 1) / 2); ans = max(ans, (n - k) * (long long) maxv); } cout << ans << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while(t--) solve(); return 0; }
-
- 1
信息
- ID
- 281
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- (无)
- 递交数
- 24
- 已通过
- 6
- 上传者