結果
| 問題 |
No.1937 Various Tournament
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 13:21:39 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 625 ms / 2,000 ms |
| コード長 | 3,929 bytes |
| コンパイル時間 | 205 ms |
| コンパイル使用メモリ | 82,188 KB |
| 実行使用メモリ | 88,352 KB |
| 最終ジャッジ日時 | 2025-05-14 13:24:24 |
| 合計ジャッジ時間 | 20,195 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 47 |
ソースコード
import collections
import itertools
def solve():
N = int(input())
S_matrix = []
for _ in range(N):
S_matrix.append(list(map(int, input().split())))
# dp[mask] is a dictionary mapping winner_player_id (1-indexed) to count_of_permutations.
# mask bits are 0-indexed: bit i corresponds to player i+1.
dp = [collections.defaultdict(int) for _ in range(1 << N)]
# Base cases: masks representing a single player.
# If player (i+1) is the only one, they win in 1 way (permutation is just [player i+1]).
for i in range(N): # i is the 0-indexed bit position
player_id = i + 1
mask = 1 << i
dp[mask][player_id] = 1
# Iterate m = size of player set (popcount of mask).
# m must be a power of 2: 2, 4, 8, ..., N.
current_m = 2
while current_m <= N:
for current_mask_val in range(1 << N):
# Only process masks with popcount equal to current_m.
# Using int.bit_count() if Python 3.10+, else bin().count('1').
# For compatibility, using bin().count('1').
if bin(current_mask_val).count('1') != current_m:
continue
# Identify players (their 0-indexed bit positions) present in current_mask_val.
players_in_current_mask_bits = []
for i in range(N):
if (current_mask_val >> i) & 1:
players_in_current_mask_bits.append(i)
# Split `current_m` players into two halves for sub-tournaments.
# `num_players_in_half` players for the "left half" permutation.
# Remaining players for the "right half" permutation.
num_players_in_half = current_m // 2
# Iterate over all ways to choose `num_players_in_half` players (by bit positions)
# from `players_in_current_mask_bits` to form `submask1`.
for chosen_bits_for_submask1 in itertools.combinations(players_in_current_mask_bits, num_players_in_half):
submask1_val = 0
for bit_pos in chosen_bits_for_submask1:
submask1_val |= (1 << bit_pos)
# Remaining players from current_mask_val form submask2_val.
submask2_val = current_mask_val ^ submask1_val
# Retrieve pre-computed results for these two submasks.
left_half_results = dp[submask1_val] # {winner_L_id: count_L_perms}
right_half_results = dp[submask2_val] # {winner_R_id: count_R_perms}
# Combine results:
# For each pair of (winner_L from left_half, winner_R from right_half).
for winner_L_id, num_perms_L in left_half_results.items():
for winner_R_id, num_perms_R in right_half_results.items():
# Simulate the match between winner_L and winner_R.
# S_matrix is 0-indexed, so use player_id - 1.
if S_matrix[winner_L_id - 1][winner_R_id - 1] == 1: # winner_L beats winner_R
# Overall winner for permutations formed this way is winner_L.
# Number of such permutations = num_perms_L * num_perms_R.
dp[current_mask_val][winner_L_id] += num_perms_L * num_perms_R
else: # winner_R beats winner_L
dp[current_mask_val][winner_R_id] += num_perms_L * num_perms_R
if current_m == N: # All masks of size N (i.e., the full set) have been processed.
break
current_m *= 2 # Next power of 2 for m.
# Final answers are in dp[(1<<N) - 1].
final_full_mask_val = (1 << N) - 1
results_for_full_tournament = dp[final_full_mask_val]
for player_id_to_print in range(1, N + 1):
print(results_for_full_tournament[player_id_to_print])
solve()
qwewe