메모리: 31256 KB, 시간: 48 ms
조합론, 다이나믹 프로그래밍, 수학
파스칼의 삼각형은 이항계수를 삼각형 형태로 배열한 것인데, 블레즈 파스칼(1623-1662)을 따라 이름 붙여졌다.
단순한 형태로, 파스칼의 삼각형은 다음과 같은 방법으로 만들 수 있다.
예를 들어, n=3이면 3번째 행의 2번째 수는 위 행의 인접한 두 수 (1과 1)을 더해서 만든다.
n=6일 때, 파스칼 삼각형의 6번째 행의 10은 5번째 행의 인접한 두 수(4와 6)을 더해서 구한다.
![]()
같은 방식으로 n=11일 때, 다음과 같은 파스칼의 삼각형을 만들 수 있다.
![]()
정수 n과 k가 주어졌을 때 파스칼의 삼각형에 있는 n번째 행에서 k번째 수를 출력하는 프로그램을 작성하시오. 이때, 이 수는 이항계수 C(n-1,k-1)임에 주의하시오.
첫째 줄에 정수 n과 k가 빈칸을 사이에 두고 차례로 주어진다. 이 때, 1 ≤ k ≤ n ≤ 30을 만족한다.
첫째 줄에 n번째 행에 있는 k번째 수를 출력한다.
DP를 처음 연습해보기 위해 풀이했던 기초 문제
점화식을 아래와같이 작성하였고, Bottom Up 방식으로 반복문을 사용하여 풀이하였다.
이를 조금 더 수학적으로 바꾸면 아래 한줄로 정리가 된다
N, M = map(int,input().split())
pascal = [[1 for _ in range(N)] for _ in range(N)]
for i in range(1, N):
for j in range(1, i):
pascal[i][j] = pascal[i-1][j] + pascal[i-1][j-1]
print(pascal[N-1][M-1])
재귀로 구현하면 아래와 같다
N, M = map(int,input().split())
def pascal(n, m):
if n in [0, 1] or m in [0, n]:
return 1
if m >= n:
return 0
return pascal(n-1, m) + pascal(n-1, m-1)
print(pascal(N - 1, M - 1))
여기에 메모이제이션을 적용하면 조금 더 빠르게 처리할 수 있다.
N, M = map(int,input().split())
mem = [[0] * N for _ in range(N)]
def pascal(n, m):
if n == m or m == 0:
return 1
if m >= n:
return 0
if mem[n][m] != 0:
return mem[n][m]
else:
mem[n][m] = pascal(n-1, m) + pascal(n-1, m-1)
return mem[n][m]
print(pascal(N - 1, M - 1))
DP에 대한 첫경험은 아니기 때문에 나름 빠르게 정답을 찾아낼 수 있었다.