링크
https://www.acmicpc.net/problem/21870
Q1. 사막에서 바늘을 찾는 방법은?
A1. 대학원생을 시킨다.
Q2. 신촌에서 자취방을 구하는 방법은?
A2. 대학원생을 시킨다.
연희동 최고의 대학원생 시철이는 오늘도 바쁘다. 그런 시철이도 이번 주말만큼은 꼭 해야 하는 일이 있었는데, 바로 자취방을 구하는 일이다!
시철이는 신촌에서 가장 아름다운 자취방을 구하고 싶다. 하지만 시철이는 매우 바빴기 때문에 직접 방을 찾아다닐 수 없었다. 그래서 시철이는 인터넷에서 본 매물번호와
(Greatest Common Divisor, 최대공약수)를 이용해 자취방의 아름다움을 예측하려 했다. 아름다움을 측정하는 자세한 방법은 다음과 같다.
교수님의 과제로 쉴 날 없는 시철이는, 그나마 더 나은 삶을 위해 자취방을 빨리 구하려고 한다. 매물번호를 이용해 자취방의 아름다움을 계산해보자!
첫째 줄에 정수 이 주어진다. ()
둘째 줄에 자취방의 매물번호를 의미하는 정수 이 주어진다. ()
자취방의 아름다움을 출력한다.
4
4 4 4 4
12
5
1 2 3 4 5
13
def gcd(a, b): # 유클리드 호제법을 이용한 최대공약수 탐색
while b != 0:
c = a % b
a = b
b = c
return a
def max_sum(start, end):
if start == end: # 리스트의 크기가 1일때
return num[start] # 한개의 원소를 반환
if start + 1 == end: # 리스트의 크기가 2일때
return num[start] + num[end] # 두개의 원소를 더해서 반환
mid = (end - start + 1) // 2 # 중간 인덱스 계산(구역을 반으로 나누기 위해)
# 왼쪽 부터 원소를 선택 하는 경우
left_sum = 0
idx = start
g = num[start]
while idx <= (start + mid - 1): # 왼쪽 구역 탐색
g = gcd(g, num[idx])
idx += 1
left_sum = g + max_sum(start + mid, end) # start값을 start+mid로 한 후 재귀호출
# 오른쪽 부터 원소를 선택 하는 경우
right_sum = 0
idx = start + mid
g = num[end]
while idx <= end: # 오른쪽 구역 탐색
g = gcd(g, num[idx])
idx += 1
right_sum = g + max_sum(start, start + mid - 1) # end값을 start + mid -1로 한 후 재귀호출
return max(left_sum, right_sum) # 왼쪽 부터 원소를 선택 하는 경우와 오른쪽 부터 원소를 선택 하는 경우중 더 큰 값 반환
import sys
def gcd(a, b): # 유클리드 호제법을 이용한 최대공약수 탐색
while b != 0:
c = a % b
a = b
b = c
return a
def max_sum(start, end):
if start == end: # 리스트의 크기가 1일때
return num[start] # 한개의 원소를 반환
if start + 1 == end: # 리스트의 크기가 2일때
return num[start] + num[end] # 두개의 원소를 더해서 반환
mid = (end - start + 1) // 2 # 중간 인덱스 계산(구역을 반으로 나누기 위해)
# 왼쪽 부터 원소를 선택 하는 경우
left_sum = 0
idx = start
g = num[start]
while idx <= (start + mid - 1): # 왼쪽 구역 탐색
g = gcd(g, num[idx])
idx += 1
left_sum = g + max_sum(start + mid, end) # start값을 start+mid로 한 후 재귀호출
# 오른쪽 부터 원소를 선택 하는 경우
right_sum = 0
idx = start + mid
g = num[end]
while idx <= end: # 오른쪽 구역 탐색
g = gcd(g, num[idx])
idx += 1
right_sum = g + max_sum(start, start + mid - 1) # end값을 start + mid -1로 한 후 재귀호출
return max(left_sum, right_sum) # 왼쪽 부터 원소를 선택 하는 경우와 오른쪽 부터 원소를 선택 하는 경우중 더 큰 값 반환
n = int(sys.stdin.readline())
num = list(map(int, sys.stdin.readline().split())) # 매물번호를 저장할 리스트
print(max_sum(0, n - 1))