문제
자연수 N 과 정수 K 가 주어졌을 때 이항 계수 (NK) 를 10,007로 나눈 나머지를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N 과 K 가 주어진다. (1 ≤ N ≤ 1,000, 0 ≤ K ≤ N )
출력
(NK)
를 10,007로 나눈 나머지를 출력한다.예제 입력 1 복사
5 2
예제 출력 1 복사
10
<풀이>
이 문제는 N과 K가 주어지면 NCK % 10007의 값을 출력하는 문제이다.
우리가 아는 단순한 조합공식 nCr = nPr / r! 을 사용하면 계산하는 도중에 오버플로우가 나버린다.
이를 방지하기 위해 조합의 성질 중 하나를 이용할 수 있다.

위의 공식은 파스칼의 삼각형을 보면 더 이해가 잘 될 것이다.

이제 이 공식을 이용해 계산한 값들을 저장시켜 계속 이용하는 dynamic programming으로 원하는 값을 구하면 된다.
<제출한 코드>
#include <iostream>
using namespace std;
long long combination(int n, int r){
long long dp[n+1][n+1];
for (int i = 1; i <= n; i++){
dp[i][i] = 1; //nCn
dp[i][0] = 1; //nC0
dp[i][1] = i; //nC1
}
for (int i = 2; i <= n; i++){
for (int j = 2; j <= n; j++){
if (i > j) dp[i][j] = (dp[i-1][j-1] + dp[i-1][j]) % 10007; //nCr = n-1Cr-1 + n-1Cr
}
}
return dp[n][r];
}
int main(void){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N, K;
cin >> N >> K;
cout << combination(N, K);
return 0;
}
'C++' 카테고리의 다른 글
[95] C++(Cpp) 백준 11053번: 가장 긴 증가하는 부분 수열 문제 (Dynamic programming 동적 계획법) (0) | 2022.11.12 |
---|---|
[94] C++(Cpp) 백준 2447번 : 별찍기 - 10 문제 (분할정복, 재귀) (0) | 2022.11.11 |
[92] C++(Cpp) 백준 15650번: N과 M (2) 문제 (백트래킹) (0) | 2022.11.04 |
[91] C++(Cpp) 백준 2579번: 계단 오르기 문제(Dynamic programming 동적 계획법) (0) | 2022.11.03 |
[90] C++(Cpp) 백준 3036번: 링 문제 (정수론, 유클리드 알고리즘) (0) | 2022.11.02 |