https://www.acmicpc.net/problem/26973
26973번: Circular Barn
For the first test case, Farmer John can remove
www.acmicpc.net
일단 N = 1인 경우를 생각해보자. 편의상 Farmer John을 FJ라 하고, Farmer Nhoj를 FN이라 부르겠다.
a(i) = 1, 2, 3인 경우는 FJ가 이기고, 4인 경우는 FN이 이긴다. FN이 이기는 경우는 i에 대해, i - j의 값이 FN이 지는 경우면 반대로 i에서는 이길 수 있으니, 이러한 j가 존재하면 된다. 존재하지 않으면 FN이 이길 것 이다.
5, 7은 FJ가 이기고, 6 - 2 = 4이기 때문에, 6 또한 FJ가 이긴다. 8인 경우는, 8 - 1, 8 - 2, 8 - 3, 8 - 5, 8 - 7 모두 안되기에, FN이 이긴다.
뭔가 4의 배수일 땐 FN이 이기고, 나머지는 FJ가 이기는 것 같다. 이 사실을 증명해보자.
1 ~ 4까지를 기저 조건이라 하자.
그렇다면
이러한 값들은 dp를 통해 구해줄 수 있다.
나머지 경우는,
나머지 경우에
import sys
from bisect import bisect_left as bl
input = sys.stdin.readline
n = 5 * int(1e6) + 1
prime = []
isp = [1] * (n + 1)
for i in range(2, n + 1):
if isp[i]: prime.append(i)
for p in prime:
if i * p > n: break
isp[i * p] = 0
if i % p == 0: break
isp[0] = 0
isp[1] = 1
p = [[] for _ in range(4)]
p[1] = [1]
for i in prime: p[i % 4].append(i)
dp = [0] * n
for i in range(1, n):
if isp[i]: dp[i] = 1
elif i % 4:
j = bl(p[i % 4], i)
j -= 1
dp[i] = dp[i - p[i % 4][j]] + 1
else:
dp[i] = max(dp[i - 1], dp[i - 2], dp[i - 3]) + 1
for _ in range(int(input())):
n = int(input())
a = list(map(int, input().split()))
tmp = float('inf')
ans = "Farmer John"
for i in a:
if dp[i] // 2 < tmp:
tmp = dp[i] // 2
if i % 4: ans = 'Farmer John'
else: ans = 'Farmer Nhoj'
print(ans)
되게 애드혹적인? 게임이론 dp 문제였다.
X를 a(i)의 범위라 할 때,
'알고리즘' 카테고리의 다른 글
코드포스 블루 달성 + 정올 얘기 + 잡설 (1) | 2023.07.27 |
---|---|
BOJ 27877 제곱수 덱 2 풀이 (2) | 2023.06.02 |
백준 16136 준하의 정수론 과제 (Divmaster) (0) | 2023.04.11 |
우선순위 큐에서 원소를 삭제하는 테크닉 (3) | 2023.04.08 |
USACO 2020 December Contest silver 파이썬 풀이 (0) | 2023.03.13 |