TechFUL: Fair or UnFair
問題概要
Tech ちゃんと FUL ちゃんは 枚のカードを用いて遊ぶことにした.
枚目のカードには数字 が書かれている.
Tech ちゃんと FUL ちゃんは交互にデッキから好きなカードを 1 枚ずつ取り出す.
デッキがなくなったとき、Tech ちゃんと FUL ちゃんはカードを 枚ずつ持っている.
Tech ちゃんと FUL ちゃんは 回のラウンドでカードの数字の大きさ比べを行う.
より大きい数字を出した方が勝ちであり、同じ数字であれば引き分けとなる.
毎回のラウンドで Tech ちゃんが先にカードを出すとき、FUL ちゃんの勝利回数の最大値を求めよ.
但し、Tech ちゃんと FUL ちゃんが自分の勝ちを最大化できるよう最善を尽くすものとする.
制約
考えたこと
数字が大きいカードが有利なので、Tech ちゃんと FUL ちゃんがデッキから選ぶカードは一意に決まる.
具体的には、 枚のカードを大きい順に交互に選択する.
Tech ちゃんが選んだカードを大きい順に とする.
また、FUL ちゃんが選んだカードを大きい順に とする.
を を満たす 1 以上 以下の最小のインデックスとする.
Tech ちゃんがカード を出すとき、FUL ちゃんは を出すのが最適である.
続いて、 は を満たす 以上 以下の最小のインデックスとする.
Tech ちゃんがカード を出すとき、FUL ちゃんは を出すのが最適である.
同様にして、FUL ちゃんが を出すのが最適であるような Tech ちゃんのカードを求めることができる.
下図を例にすると、
より、Tech ちゃんが を出すとき、FUL ちゃんは を出すべきである.
より、Tech ちゃんが を出すとき、FUL ちゃんは を出すべきである.
より、Tech ちゃんが を出すとき、FUL ちゃんは を出すべきである.
より、Tech ちゃんが を出すとき、FUL ちゃんは を出すべきである.
Tech ちゃんが を出すとき、FUL ちゃんは から適当に出せばいい.
#include <bits/stdc++.h> using namespace std; int main() { int N; cin >> N; vector<int> a(2 * N); for (int i = 0; i < a.size(); ++i) { cin >> a[i]; } sort(a.begin(), a.end(), greater<int>()); vector<int> T, F; for (int i = 0; i < N; ++i) { T.push_back(a[2 * i]); F.push_back(a[2 * i + 1]); } int ans = 0, i = 0, j = 0; while (i < N && j < N) { if (T[i] < F[j]) { j++; ans++; } i++; } cout << ans << endl; }