Programming/백준
[골드 4] 백준 20159 - 동작 그만. 밑장 빼기냐?
pental
2025. 7. 9. 16:56
https://www.acmicpc.net/problem/20159
풀이
플레이어가 번갈아 가면서 카드를 가져간다.
짝수 번째(0, 2, 4 … )는 내차례, 홀수 번째는 상대 차례이다.
마지막 카드 1장을 상다 차례에서 내가 가져도록 1번의 밑장 빼기를 허용한다.
최대 점수를 얻기 위해 밑장 빼기를 어느 위치에서 할지를 결정해야한다.
psum0 = [0] * N # 내 차례에서의 누적합
psum1 = [0] * N # 상대 차례에서의 누적합
psum0[0] = A[0]
psum1[0] = 0
for i in range(1, N):
if i % 2 == 0: # 내 차례
psum0[i] = psum0[i - 1] + A[i]
psum1[i] = psum1[i - 1]
else: # 상대 차례
psum0[i] = psum0[i - 1]
psum1[i] = psum1[i - 1] + A[i]
i번째 카드가 내 차례인지 상대 차례인지를 나누어 각각의 누적합 배열을 구성한다.
def range_sum0(l, r): ...
def range_sum1(l, r): ...
누적합을 이용한 구간 합 함수를 각각 구현한다.
sum0의 경우 내 차례인 카드들 중 l ~ r의 합을 나타내고, sum1의 경우 상대 차례인 카드들 중 l ~ r의 합을 나타낸다.
밑장 빼기 시뮬레이션은 다음과 같이 진행한다.
answer = psum0[N - 1] # 밑장 안 뺐을 경우의 기본 점수
for i in range(N):
score = range_sum0(0, i - 1) + range_sum1(i, N - 2)
if i % 2 == 0:
score += A[N - 1] # 밑장 빼기 성공하면 마지막 카드 얻음
answer = max(answer, score)
i는 밑장을 빼는 위치이고, range_sum0, range_sum1을 통해서 밑짱 빼기 시뮬레이션을 진행한다.
코드
# 백준 20159 - 동작 그만. 밑장 빼기냐?
# 분류 : 누적합
N = int(input())
A = list(map(int, input().split()))
psum0 = [0] * N
psum1 = [0] * N
psum0[0] = A[0]
psum1[0] = 0
for i in range(1, N) :
if i % 2 == 0 :
psum0[i] = psum0[i - 1] + A[i]
psum1[i] = psum1[i - 1]
else :
psum0[i] = psum0[i - 1]
psum1[i] = psum1[i - 1] + A[i]
def range_sum0(l, r) :
if l > r :
return 0
ret = psum0[r]
if l > 0 :
ret -= psum0[l - 1]
return ret
def range_sum1(l, r) :
if l > r :
return 0
ret = psum1[r]
if l > 0 :
ret -= psum1[l - 1]
return ret
answer = psum0[N - 1]
for i in range(N) :
score = range_sum0(0, i - 1) + range_sum1(i, N - 2)
if i % 2 == 0 :
score += A[N - 1]
answer = max(answer, score)
print(answer)