(BOJ)-2559, Python
(BOJ)-2559, Python
문제 요약
출처: (BOJ)2559 - 수열
수열 N
이 주어졌을 때, K
일 연속된 원소의 합이 가장 큰 값을 찾는 문제이다.
N
: 원소의 수K
: 연속된 원소의 수
접근 과정
1. 완전탐색 접근
리스트를 순회하며, 각 인덱스 i
부터 i+K-1
까지의 부분합을 모두 구하고 가장 높은 값을 찾아내자!
코드 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
N, K = map(int, input().split())
arr = list(map(int, input().split()))
answer = []
for i in range(N+1):
sum = 0
if i+K-1 == len(arr)-1:
for j in range(i, i+K):
sum += arr[j]
answer.append(sum)
break
else:
for j in range(i, i+K):
sum += arr[j]
answer.append(sum)
print(max(answer))
2. 누적합 접근
위의 완전탐색 방법은 직관적이지만, 각 인덱스마다 구간의 부분합을 매번 계산하므로 비효율적인 문제가 있었음을 알 수 있었다. 이를 해결하기 위해 누적합(prefix sum) 을 이용할 수 있는데, 누적합은 각 원소의 합을 누적하여 계산해둔 배열이다. 이를 통해 반복적인 부분합 계산을 줄일 수 있다는 점만 이해하면 된다. 예제를 통해 어떻게 사용되는지 알아보도록 하자!
수열: [1, 2, 3, 4, 5]
누적합: [1, 3, 6, 10, 15]
위 수열에서, 누적합의 각 값은 다음과 같이 계산된다 :
- 1:
1
- 3:
1 + 2
- 6:
1 + 2 + 3
- 10:
1 + 2 + 3 + 4
- 15:
1 + 2 + 3 + 4 + 5
입력값으로 N=5, K=2
와 위 수열이 주어졌다고 하자. 여기서, 길이가 2이고 연속된 구간합의 최대값을 구하는 문제이기에, 답은 쉽게 9(4+5)
임을 알 수 있다. 이를 누적합으로 풀어보면, 누적합에서 5번째 원소는 15
이고, 누적합에서 3번째 원소는 6
이다. 따라서, 구간 [4, 5]
의 합은 누적합[5]-누적합[5-2(=K)]
로 계산할 수 있다!
코드 구현
1
2
3
4
5
6
7
8
9
10
11
12
N, K = map(int, input().split())
arr = list(map(int, input().split()))
prefix = [0 for _ in range(N+1)]
for i in range(N):
prefix[i+1] = prefix[i] + arr[i]
answer = []
for k in range(K,N+1):
answer.append(prefix[k] - prefix[k-K])
print(max(answer))
회고
같은 문제에 대해 다양한 접근 방법으로 문제를 풀어보면서, 바라보는 시야를 조금이나마 넓힐 수 있었다. 그리고 누적합이라는 간단하면서도 효율적인 아이디어를 얻어간 것 같다!
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.