문제 풀이에 앞서 그리디 알고리즘을 간단하게 짚고 넘어가보자.
그리디 알고리즘은 비교적 간단하고 자주 사용되는 알고리즘이다.
이 알고리즘은 특정한 조건 내에서 가능한 가장 좋은 해
를 찾기 위해 매번 다른 값을 시도해 보는 방식으로 접근한다.
일반적으로 시간 및 공간 복잡도가 낮아 효율적인 솔루션
을 제공한다.
일반적으로는 최적 분할 문제
, 최대 값 문제
및 최소 값 문제
에 적용할 수 있다. 이 외에도 다양한 다른 문제에 대해 그리디 알고리즘을 사용할 수 있다.
예를 들어 다음과 같은 숫자 배열이 있다고 가정해보자 [2, 3, 7, 8, 10]
여기에서 주어진 숫자들을 사용하여 최대 합을 가지는 부분 집합
을 찾는 문제를 해결하고자 한다.
이 때 그리디 알고리즘이 적용되는데, 숫자가 적어도 하나 이상 포함되는 부분 집합을 구하기 위해 다음과 같은 과정을 따른다.
첫 번째 원소
를 선택한다.다음 원소
를 선택하고 지금까지 선택한 원소의 합과 비교
한다.더 큰 값을 선택
한다.그리디 알고리즘은 비교적 간단하고 자주 사용되는 알고리즘이다.
가장 큰 장점은 시간 및 공간 복잡도가 낮아 효율적인 해를 찾는 것!
즉 모든 문제는 완전탐색으로 풀 수 있지만,
이 알고리즘을 채택한다면 더 빠르게 풀 수 있다!
하지만 이 알고리즘을 사용하기 전에 이 방법이 정말 맞는지 판별하기가 어렵기 때문에
꽤 어려운 알고리즘이다.
입력받은 배열을 사용하여 가장 큰 수를 만드는 문제이다.
1. N개의 자연수를 가진 배열은 정렬되어있지 않고
2. 총 M번 더할 수 있으며
3. 하나의 인덱스 당 K번 초과하여 더할 수 없다.
let input = readLine()!.split(separator: " ").map{ Int(String($0))! }
var (N, M, K) = (input[0], input[1], input[2])
var array = readLine()!.split(separator: " ").map{ Int(String($0))! }
array.sort()
let first = array[N - 1] // 가장 큰 수
let second = array[N - 2] // 두번째로 큰 수
var result = 0
var count = 1
for _ in 0 ..< M {
if count <= K {
result += first
count += 1
} else {
result += second
count = 1
}
}
print(result)