Luogu
算法
思路
由于 Bessie 预先知道了 Elsie 的出牌策略, 所以可以贪心, 考虑每次都出比 Elsie 大一点点的牌, 如果没有就改变规则, 这样可以保证得分最大化.
记 fi 表示每次都出大一点点的牌最多可以赢几次, gi 相反.
则最后的答案为 maxin{fi+gi+1}
关于重复的证明见 Link
代码
#include <bits/stdc++.h> using namespace std;
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int n; cin >> n; vector<int> Elsie(n); set<int, greater<int>> BessieG; set<int, less<int>> BessieL; vector<bool> used(2 * n + 1, false); for (int i = 0; i < n; i++) { cin >> Elsie[i]; used[Elsie[i]] = true; } for (int i = 1; i <= 2 * n; i++) { if (used[i] == false) { BessieG.insert(i); BessieL.insert(i); } } vector<int> f(n + 2), g(n + 2); for (int i = 1; i <= n; i++) { set<int>::iterator found = BessieL.lower_bound(Elsie[i - 1]); if (found != BessieL.end()) { BessieL.erase(found); f[i] = f[i - 1] + 1; } else { f[i] = f[i - 1]; } } for (int i = n; i >= 1; i--) { set<int>::iterator found = BessieG.lower_bound(Elsie[i - 1]); if (found != BessieG.end()) { BessieG.erase(found); g[i] = g[i + 1] + 1; } else { g[i] = g[i + 1]; } } int answer = 0; for (int i = 0; i <= n; i++) { answer = max(answer, f[i] + g[i + 1]); } cout << answer << '\n'; return 0; }
|