AtCoder Beginner Contest 031 C – 数列ゲーム をPython3で解く

Share

AtCoder上にある問題のうち、AtCoder Problemsでdiff 800以上と判定されているものを順番に解いていく企画。
基本的な考え方は全てコード中のコメントに入れてあるので、参照のこと。

出典:
AtCoder Beginner Contest 031 C – 数列ゲーム

古いのでdiffが高めになっている問題。何も考えず全探索でいい……のだが、そのままだと芸がないので、一応累積和を使用してみた。もっとも、制約から言うと全く必要ない。

# AtCoder Beginner Contest 031 C - 数列ゲーム
# https://atcoder.jp/contests/abc031/tasks/abc031_c
# tag: 数列 連続部分列 累積和 ゲーム 二人ゲーム 高橋君 青木君

# 考察を行ってもいいが、制約が 1 <= N <= 50 と緩いので
# 何も考えず全探索するのが楽で早い。

def main():
N = int(input())
A = list(map(int, input().split()))

# あらかじめ累積和を奇数・偶数番目のもので取っておく。
# 実際には制約が緩いので、累積和を使用する必要はない。
# まあ練習と思って……
csum = [0, 0]
for i, a in enumerate(A):
csum.append(csum[i] + a)

result = -10**10

# t_pos: 高橋君の選ぶ場所
# a_pos: 青木君の選ぶ場所 として全探索。
for t_pos in range(N):
tak_final_score = 0
aok_max_score = -10**10
for a_pos in range(N):
if t_pos == a_pos:
continue

# 使用する数列の範囲。
left, right = min(t_pos, a_pos), max(t_pos, a_pos)

tak_left, aok_left = left, left + 1

# 選んだ長さによって、右端をどちらが取るかは変わる。
if (right - left) % 2 == 0:
tak_right, aok_right = right, right - 1
else:
aok_right, tak_right = right, right - 1

# 累積和を用いて点数を計算
tak_score = csum[tak_right+2] - csum[tak_left]
aok_score = csum[aok_right+2] - csum[aok_left]

# 青木君のスコアが最大になるところが、高橋君のスコア。
if aok_score > aok_max_score:
aok_max_score = aok_score
tak_final_score = tak_score

# 高橋君のスコアが確定したら、今までの最大値と比較する。
if result < tak_final_score:
result = tak_final_score

print(result)

main()
Share

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です