2022. 8. 3. 02:57ㆍSwift 코딩테스트/Swift 백준 문제 풀이
스위프트의 경우 pascal(n: n-1, k: k-1) + pascal(n: n-1, k: k)를 DP를 이용해서 풀면 시간초과의 문제가 생긴다.
-> 시간초과를 해결하기 위해서는 2차원 배열에 값들을 저장해서 c[n-1][k-1] + c[n-1][k]를 계산해서 문제를 풀 수 있다.
1. 먼저 이항계수의 성질은 nCk = n-1Ck-1 + n-1Ck
2. nC0 = 1, nCn = 1
을 사용해서 문제를 풀 수 있다.
위의 2가지를 사용한다면 풀 수 있는 문제이지만, 한 번에 풀지 못해 다른 블로그를 참고했을 때 이해 되지 않던 점을 정리해보았다.
1. 범위를 k가 n을 초과할 수 없는 이유
- 이항계수 값을 저장할 배열은 [N+1][N+1]개의 사각형 형태의 이차원 배열로 저장했지만
당연히 이항계수에서 k는 n을 초과할 수 없는 삼각형 형태이기 때문에 k는 n을 초과할 수 없다.
2. 코드에서 nCn(예) 4C4)는 고려하지 않는 이유
- if n == 0 || k == 0 은 0C0, 1C0, 2C0, 3C0...을 의미하고, 이때 값은 1이다.
- 4C4 = 3C3 + 3C4
3C4는 배열에서 c[3][4]로 0의 값을 가지고 있기 때문에 무시할 수 있다.
따라서 4C4 = 3C3 + 3C4(0) = 2C2 + 2C3(0) = 1C1 + 1C2(0) = 0C0(1) + 0C1(0) = 1
= 1의 값을 갖는다.
- 하지만 조건문에 k == n 의 조건을 걸어도 무방하다.
3. 배열에 % 10007의 값을 저장하는 이유
- n의 값은 1000이하의 값을 가진다, 이때 수가 무수히 크기 때문에 %10007의 나머지 값을 저장하는 것
- 나머지 값들끼리 더해서 나머지 값을 계산해도 원래의 합에 나머지 값을 계산한 것과 동일하기 때문에 상관없다.
//코드
import Foundation
let input = readLine()!.split(separator: " ").map{Int($0)!}
let N = input[0]
let K = input[1]
var c: [[Int]] = Array(repeating: Array(repeating: 0, count: N+1), count: N+1)
//c(n, k) = c(n-1, k-1) + c(n-1, k)
for n in 0...N{
for k in 0...n{
if n == 0 || k == 0 || k == n {
c[n][k] = 1
}else{
c[n][k] = (c[n - 1][k - 1] % 10007 + c[n - 1][k] % 10007) % 10007
}
}
}
print(c[N][K])
'Swift 코딩테스트 > Swift 백준 문제 풀이' 카테고리의 다른 글
[Swift 코테] 백준 24313 알고리즘 수업 - 점근적 표기 1 (0) | 2023.04.07 |
---|---|
[Swift 코테] 백준 15649, 15650, 15651, 15652 N과 M (0) | 2022.09.05 |
[Swift 코테] 백준 2981검문 (swift 런타임 에러) (0) | 2022.08.02 |
[Swift 코테] 백준 2609 최대공약수와 최소공배수 (0) | 2022.07.27 |
[Swift 코테] 백준 1004 어린왕자 (0) | 2022.07.19 |