ps | |
---|---|
링크 | acmicpc.net/… |
출처 | BOJ |
문제 번호 | 31289 |
문제명 | 기부왕의 님게임 |
레벨 | 플래티넘 4 |
분류 |
게임 이론 |
시간복잡도 | O(n^3) |
인풋사이즈 | n<=200 |
사용한 언어 | Python 3.11 |
제출기록 | 97680KB / 1428ms |
최고기록 | 1428ms |
해결날짜 | 2024/01/31 |
"""Solution code for "BOJ 31289. 기부왕의 님게임".
- Problem link: https://www.acmicpc.net/problem/31289
- Solution link: http://www.teferi.net/ps/problems/boj/31289
Tags: [game theory]
"""
import itertools
import sys
MAX = 200
INF = float('inf')
def precompute():
dp = [[[INF] * (MAX + 1) for _ in range(MAX + 1)] for _ in range(MAX + 1)]
for x, y, z in itertools.combinations_with_replacement(range(MAX + 1), 3):
tot = x + y + z
if x ^ y ^ z == 0:
dp_cur = tot - min(
itertools.chain(dp[y][z][:x], dp[z][x][:y], dp[x][y][:z]),
default=0,
)
else:
take_x = dp[y ^ z][y][z] if y ^ z < x else INF
take_y = dp[x][x ^ z][z] if x ^ z < y else INF
take_z = dp[x][y][x ^ y] if x ^ y < z else INF
dp_cur = tot - min(take_x, take_y, take_z)
dp[x][y][z] = dp[x][z][y] = dp_cur
dp[y][x][z] = dp[y][z][x] = dp_cur
dp[z][x][y] = dp[z][y][x] = dp_cur
return dp
def main():
dp = precompute()
T = int(sys.stdin.readline())
for _ in range(T):
x, y, z = [int(x) for x in sys.stdin.readline().split()]
fp = dp[x][y][z] * 10000
sp = (x + y + z) * 10000 - fp
print(fp, sp)
if __name__ == '__main__':
main()