Official

B - カードの裏返し / Flipping Cards Editorial by MtSaka


\(N\) 枚のうち \(K\) 枚を裏返す方法の場合の数は \(\binom{N}{K}\) 通りあります。

これらを全探索して、それぞれについて上を向いている面の合計値を求め、その最大値を計算すると答えが求まります。

裏返す方法をきっかり\(\binom{N}{K}\) 通り列挙することも可能ですが、bit全探索の要領で\(2^N\) 通り探索して、立っているbtiの個数が \(K\) 個であるときだけ上を向いている面の合計を計算する方法でもよいです。

この場合時間計算量 \(\mathrm{O}(2^N+N\binom{N}{K})\) となり、十分高速です。

Bonus: この問題を \(\mathrm{O}(N\log N)\) で解いてください。

実装例(C++)

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n, k;
    cin >> n >> k;
    vector<int> f(n), b(n);
    for (int i = 0; i < n; ++i) cin >> f[i] >> b[i];
    int ans = 0;
    for (int bit = 0; bit < (1 << n); ++bit) {
        if (popcount((unsigned)bit) == k) {
            int sum = 0;
            for (int i = 0; i < n; ++i) {
                if ((bit >> i) & 1)
                    sum += b[i];
                else
                    sum += f[i];
            }
            ans = max(ans, sum);
        }
    }
    cout << ans << endl;
}