Official

F - World Tour Finals Editorial by nok0


まず、各プレイヤーの現在の総合得点を計算しましょう。これは入力を読み込み、for 文で各問題を解いたかを確認することで可能です。

次に、条件を満たすために必要な問題数を各プレイヤーについて求めましょう。

ここで、以下が成立します。

  • プレイヤー \(i\) が解く問題数を最小化するために解くべき問題は、まだ解いてない問題のうち点数が高い順に何個かである。

これは、上の条件を満たさない選び方の場合、ある選んでない問題が存在して、選んだ問題の一つより点数が高いため、選ぶかを入れ替えることによって総合得点が増加することから従います。

よって、各プレイヤーについて解いてない問題を点数の降順に並び替え、他の全プレイヤーの総合得点よりも高くなるまで解いてない問題を順に解くという方法を実装すればよいです。

実装例(C++):

#include <bits/stdc++.h>
using namespace std;

#define rep(i, x) for(int i = 0; i < (x); i++)

int main() {
	int n, m;
	cin >> n >> m;
	vector<int> a(m);
	rep(i, m) cin >> a[i];
	vector<string> s(n);
	rep(i, n) cin >> s[i];
	vector<int> now_sc(n);
	rep(i, n) now_sc[i] = i + 1;
	rep(i, n) rep(j, m) if(s[i][j] == 'o') now_sc[i] += a[j];
	int mx = *max_element(now_sc.begin(), now_sc.end());
	rep(i, n) {
		vector<int> nokori;
		rep(j, m) if(s[i][j] == 'x') nokori.push_back(a[j]);
		sort(nokori.rbegin(), nokori.rend());
		int ans = 0;
		while(now_sc[i] < mx) {
			now_sc[i] += nokori[ans++];
		}
		cout << ans << endl;
	}
}

posted:
last update: