Home기술 & 코딩코딩 테스트백준 11051 파이썬 이항계수와 동적 계획법 DP

백준 11051 파이썬 이항계수와 동적 계획법 DP

이항계수는 조합론에서 핵심적인 개념으로, 다양한 수학적 문제와 알고리즘에 활용됩니다. 이 글에서는 이항계수의 개념부터 계산 방법, 그리고 프로그래밍에서의 효율적인 구현 방법까지 상세히 알아보겠습니다.

📚 이항계수의 기본 개념

이항계수는 수학적으로 매우 중요한 개념으로, 조합론에서 빈번하게 사용됩니다.

1. 이항계수의 정의

– 이항계수(binomial coefficient)는 이항식을 이항 정리로 전개했을 때 각 항의 계수입니다2.
– 크기가 n인 집합에서 크기가 k인 부분집합을 선택하는 방법의 수를 나타냅니다2.
– 표기법으로는 nCk, C(n,k) 또는 **$\binom{n}{k}$**를 사용합니다.
– 수식으로는 **nCk = n! / (k! × (n-k)!)**로 정의됩니다7.

2. 이항계수의 성질

nC0 = nCn = 1: n개 중 0개 또는 n개를 모두 선택하는 방법은 각각 1가지뿐입니다7.
nCk = nC(n-k): 이항계수는 대칭적인 성질을 가집니다7.
nCk = (n-1)C(k-1) + (n-1)Ck: 이는 파스칼의 법칙으로 알려진 중요한 점화식입니다7.

🔺 파스칼의 삼각형

이항계수를 시각적으로 표현한 파스칼의 삼각형은 수학적 패턴을 이해하는 데 큰 도움이 됩니다.

1. 파스칼 삼각형의 구조

– 파스칼의 삼각형은 이항계수를 삼각형 모양으로 배열한 것입니다3.
– 첫 번째 줄에는 1을 쓰고, 그 다음 줄을 만들 때는 바로 위의 왼쪽 숫자와 오른쪽 숫자를 더합니다3.
– 삼각형의 각 행은 이항계수의 값을 나타내며, n번째 행의 k번째 값은 nCk입니다3.

2. 파스칼 삼각형의 성질

– 각 행의 첫 번째와 마지막 숫자는 항상 1입니다3.
– 삼각형의 각 수는 바로 위의 두 수의 합과 같습니다7.
– 이 성질은 이항계수의 점화식 nCk = (n-1)C(k-1) + (n-1)Ck와 정확히 일치합니다7.

💻 이항계수의 프로그래밍적 구현

이항계수 계산은 다양한 알고리즘 문제에서 자주 등장하며, 효율적인 구현이 중요합니다.

1. 단순 재귀 방식

– 가장 직관적인 방법으로, 점화식을 그대로 구현합니다7.
– 코드는 간단하지만, 중복 계산으로 인해 O(2^n)의 시간 복잡도를 가집니다7.
– 큰 입력값에 대해서는 제한 시간 내에 문제를 해결할 수 없습니다7.

def bino(n, k):
    if k == 0 or n == k:
        return 1
    return bino(n-1, k-1) + bino(n-1, k)

2. 메모이제이션을 활용한 재귀 (Top-down DP)

– 한 번 계산한 부분 문제의 결과를 저장하여 중복 계산을 방지합니다5.
– 필요한 부분만 계산하여 효율적입니다5.
– 재귀 함수 호출 오버헤드가 있지만, 필요한 값만 계산하므로 특정 상황에서 유리합니다5.

def bino(n, k):
    if cache[n][k] != 0:
        return cache[n][k]
    if k == 0 or n == k:
        return 1
    cache[n][k] = (bino(n-1, k-1) + bino(n-1, k)) % MOD
    return cache[n][k]

3. 반복문을 이용한 DP (Bottom-up DP)

– 작은 부분 문제부터 차례로 해결하며 테이블을 채워나갑니다5.
– 함수 호출 오버헤드가 없어 일반적으로 더 빠릅니다5.
– 모든 부분 문제를 해결해야 할 때 유리합니다5.

for i in range(1001):
    cache[i][0] = 1
    cache[i][i] = 1
    for j in range(1, i):
        cache[i][j] = (cache[i-1][j-1] + cache[i-1][j]) % MOD

https://www.acmicpc.net/problem/11051

메모이제이션이나 반복문으로 해결 가능


import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**7) # 재귀 깊이 제한 늘리기

# 일단 단순하게 재귀로 구현
# 1000 500 넣으면 시간초과
MOD = 10007
N,K = map(int, input().split())
def bino(n,k):
    if k == 0 or n == k:
        return 1
    return bino(n-1,k-1) + bino(n-1,k)
print(bino(N,K))

# 메모이제이션을 이용한 재귀
MOD = 10007
N,K = map(int, input().split())
cache = [[0] * 1001 for _ in range(1001)]
def bino(n,k):
  if cache[n][k] != 0:
    return cache[n][k]
  if k == 0 or n == k:
    return 1
  cache[n][k] = (bino(n-1,k-1) + bino(n-1,k)) % MOD
  return cache[n][k]
print(bino(N,K))

# 반복문을 이용한 DP
MOD = 10007
N,K = map(int, input().split())
cache = [[0] * 1001 for _ in range(1001)]
for i in range(1001):
    cache[i][0] = 1
    cache[i][i] = 1
    for j in range(1, i):
        cache[i][j] = cache[i-1][j-1] + cache[i-1][j]
        cache[i][j] %= MOD
print(cache[N][K])

🔄 재귀 깊이 제한과 대규모 계산

재귀 함수를 사용할 때는 몇 가지 제약 사항에 주의해야 합니다.

1. 파이썬의 재귀 깊이 제한

– 파이썬의 기본 재귀 깊이 제한은 1000입니다1113.
– 이를 초과하면 RecursionError가 발생합니다14.
– sys.setrecursionlimit() 함수를 사용하여 제한을 늘릴 수 있습니다1113.

import sys
sys.setrecursionlimit(10**6)  # 재귀 깊이를 백만으로 설정

2. 대규모 이항계수 계산과 모듈러 연산

– 이항계수 값은 n과 k가 커질수록 매우 빠르게 증가합니다4.
– 오버플로우를 방지하기 위해 모듈러 연산을 사용합니다4.
– 모듈러 연산의 성질: (a + b) % n = ((a % n) + (b % n)) % n4.
– 이를 활용하여 큰 이항계수 값도 효율적으로 계산할 수 있습니다4.

🔍 Top-down DP와 Bottom-up DP 비교

두 방식은 각각 장단점이 있어 상황에 따라 적절한 방법을 선택해야 합니다.

1. Top-down DP (메모이제이션)

장점: 직관적인 구현, 필요한 부분만 계산, 코드 가독성이 좋음5.
단점: 재귀 함수 호출 오버헤드, 스택 메모리 사용, 재귀 깊이 제한5.
적합한 경우: 모든 부분 문제를 계산할 필요가 없을 때5.

2. Bottom-up DP (테이블레이션)

장점: 재귀 없이 반복문만 사용하여 메모리와 시간 효율적5.
단점: DP 테이블을 채우는 순서를 정확히 파악해야 함5.
적합한 경우: 모든 부분 문제를 계산해야 할 때, 메모리 효율성이 중요할 때5.

📐 이항계수의 응용

이항계수는 다양한 분야에서 응용됩니다.

1. 조합론적 응용

– 조합의 수 계산: n개 중 k개를 선택하는 방법의 수2.
– 카탈랑 수 계산: 다양한 조합론적 문제의 해법2.
– 중복집합 선택: n개 중 k개를 중복 허용하여 선택하는 방법의 수2.

2. 대수학과 통계학

– 이항식 전개: (x + y)^n의 전개2.
– 이항분포: 확률 분포 정의2.
– 정수론: 베르트랑의 공준 증명, 아페리 상수 관련 급수2.

📝 결론

이항계수는 수학과 컴퓨터 과학에서 중요한 개념으로, 효율적인 계산 방법을 이해하는 것이 알고리즘 문제 해결에 큰 도움이 됩니다.

– 이항계수는 조합론, 대수학, 통계학 등 다양한 분야에서 활용됩니다2.
– 계산 방법으로는 단순 재귀, Top-down DP, Bottom-up DP 등이 있으며, 각각 장단점이 있습니다57.
– 파이썬에서 재귀를 사용할 때는 재귀 깊이 제한에 주의해야 합니다111314.
– 대규모 계산 시 모듈러 연산을 활용하여 오버플로우를 방지할 수 있습니다4.

이항계수의 개념과 계산 방법을 제대로 이해한다면, 다양한 알고리즘 문제를 효율적으로 해결할 수 있을 것입니다.

Citations:

  1. https://www.acmicpc.net/problem/11051
  2. https://ko.wikipedia.org/wiki/%EC%9D%B4%ED%95%AD_%EA%B3%84%EC%88%98
  3. https://ko.wikipedia.org/wiki/%ED%8C%8C%EC%8A%A4%EC%B9%BC%EC%9D%98_%EC%82%BC%EA%B0%81%ED%98%95
  4. https://suri78.tistory.com/41
  5. https://devruby7777.tistory.com/entry/Top-down-DP%EC%99%80-Bottom-up-DP%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90%EA%B3%BC-%EC%9E%A5%EB%8B%A8%EC%A0%90-%EC%93%B0%EB%8A%94-%EA%B2%BD%EC%9A%B0
  6. https://jlog1016.tistory.com/23
  7. https://rh-tn.tistory.com/32
  8. https://optboy.github.io/markdown/2020/03/01/markdown.html
  9. https://blog.naver.com/surfer_of_life/222004981175
  10. https://velog.io/@newdana01/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9D%B4%ED%95%AD%EA%B3%84%EC%88%98%EB%9E%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B5%AC%ED%98%84
  11. https://makasti.tistory.com/108
  12. https://blog.naver.com/prayer2k/222632101723
  13. https://ye5ni.tistory.com/178
  14. https://dinae.tistory.com/73
  15. https://shoark7.github.io/programming/algorithm/3-ways-to-get-binomial-coefficients
  16. https://noanomal.tistory.com/509
  17. https://yabmoons.tistory.com/539
  18. https://www.youtube.com/watch?v=M6tVz2g6Q3s
  19. https://blog.naver.com/vollollov/220947452823
  20. https://ldgeao99.tistory.com/369
  21. https://blog.naver.com/jinhan814/222603789811
  22. https://growth-coder.tistory.com/90
  23. https://blog.naver.com/junhyuk7272/222053814549
  24. https://indv-wrappedmath.tistory.com/entry/%ED%8C%8C%EC%8A%A4%EC%B9%BC%EC%9D%98-%EC%82%BC%EA%B0%81%ED%98%95
  25. https://velog.io/@e414/%EC%BD%94%EB%94%A9-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%A1%B0%ED%95%A9-%EC%9D%B4%ED%95%AD%EA%B3%84%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B02
  26. https://velog.io/@kimdukbae/%EB%8B%A4%EC%9D%B4%EB%82%98%EB%AF%B9-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-Dynamic-Programming
  27. https://www.acmicpc.net/problem/11051
  28. https://kbhetrr.dev/blog/binomial-coefficient/
  29. https://hgk5722.tistory.com/93
  30. https://seungjuitmemo.tistory.com/85
  31. https://mindorizip.tistory.com/80
  32. https://www.youtube.com/watch?v=Dcd9kHu6c54
  33. https://velog.io/@chulxmin/Python-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%B5%9C%EB%8C%80-%EC%9E%AC%EA%B7%80-%EC%A0%9C%ED%95%9C-%ED%92%80%EA%B8%B0
  34. https://velog.io/@imdemo/Tech-Markdown%EB%A7%88%ED%81%AC%EB%8B%A4%EC%9A%B4-%EC%A0%95%EB%A6%AC
  35. https://brunch.co.kr/@donland/41
  36. https://dykm.tistory.com/72
  37. https://haamjamie.tistory.com/6
  38. https://velog.io/@if-else/%EC%9E%90%EC%A3%BC-%EC%93%B0%EC%9D%B4%EB%8A%94-%EB%A7%88%ED%81%AC%EB%8B%A4%EC%9A%B4-%EB%AC%B8%EB%B2%95%EB%93%A4-with-%EC%98%B5%EC%8B%9C%EB%94%94%EC%96%B8
  39. https://brunch.co.kr/@or24/35

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments