[BOJ-16395] 파스칼의 삼각형 Python 풀이

ParkJunHa·2023년 6월 3일

BOJ

목록 보기
69/85
post-thumbnail

[Silver V] 파스칼의 삼각형 - 16395

문제 링크

성능 요약

메모리: 31256 KB, 시간: 48 ms

분류

조합론, 다이나믹 프로그래밍, 수학

문제 설명

파스칼의 삼각형은 이항계수를 삼각형 형태로 배열한 것인데, 블레즈 파스칼(1623-1662)을 따라 이름 붙여졌다.

단순한 형태로, 파스칼의 삼각형은 다음과 같은 방법으로 만들 수 있다.

  1. N번째 행에는 N개의 수가 있다.
  2. 첫 번째 행은 1이다.
  3. 두 번째 행부터, 각 행의 양 끝의 값은 1이고, 나머지 수의 값은 바로 위 행의 인접한 두 수의 합이다.

예를 들어, 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 방식으로 반복문을 사용하여 풀이하였다.

{a(0,0)=1a(n,m)=1if n=0 || (n=0 & m=n)a(n,m)=a(n1,m)+a(n1,m1)\begin{cases} a_{(0,0)} = 1 \\ a_{(n,m)} = 1 \cdots \text{if n=0 || (n=0 \& m=n)}\\ a_{(n,m)} = a_{(n-1,m)}+a_{(n-1,m-1)} \\ \end{cases}

이를 조금 더 수학적으로 바꾸면 아래 한줄로 정리가 된다

nCm=(n1)C(m1)_{n}C_{m} =\,_{(n-1)}C_{(m-1)}

코드

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에 대한 첫경험은 아니기 때문에 나름 빠르게 정답을 찾아낼 수 있었다.

profile
PS린이

0개의 댓글