문제 내용
전에 풀은 이항계수를 10007로 나눈 나머지를 출력하라.
문제 풀이
이게 무슨 개꿀 문제인가! 전에 풀었던 내용에 % 10007 만 붙이면되는거아님?ㅋㅋ 근데 왜이렇게 정답률이 낮지? 했는데...역시나 생각보다 어려운문제다.
#include <iostream>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cout.tie(0); cin.tie(0);
int n, k;
cin >> n >> k;
int up = 1;
for (int i = 0; i < k; i++)
{
up *= n;
n--;
}
int down = 1;
int down_k = k;
for (int i = 0; i < down_k; i++)
{
down *= k;
k--;
}
cout << up / down % 10007;
}
런타임 에러, 인티져 오버플로우가 떠버린다.
인티져 오버플로우는 int 의 값을 벗어났을때 뜨는 오류라고 한다. 즉 , 너무 큰값이 들어간다는 뜻.
뭐지.. 그럼 어떻게하지? 이항 계수의 특성이 있나? 미리 값을 나누어서 범위를 넘어설 수 없게 할 수 있나? 했는데
두둥! 이럴땐 문제를 천천히 다시 한번 살펴보면 생각 못한 힌트가 나온다.
동적 계획법이요? ( 동적계획법에 대한 문제도 많이 나오니, 궁금한건 구글에 동적계획법을 검색해보자. )
동적 계획법 문제를 여러개 풀다보면 ,
대충 동적계획법은 데이터들의 규칙을 이용해 그 해당 하는 값을 배열에 저장해두고 그것을 이용해 문제를 더 간단하고 빠르게 풀 수 있는 방법이다.
그래서 이 문제는 이제 어떻게 푸느냐?
이항계수의 성질을 또 알아야한다. 어휴!
https://ko.wikipedia.org/wiki/%EC%9D%B4%ED%95%AD_%EA%B3%84%EC%88%98
이항 계수 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 조합론에서 이항 계수(二項係數, 영어: binomial coefficient)는 이항식을 이항 정리로 전개했을 때 각 항의 계수이며, 주어진 크기의 (순서 없는) 조합의 가짓수이다.
ko.wikipedia.org
다 볼 필요는 없고,
점화식과 이 점화식을 통하면
n (행 인덱스)
k (열 인덱스) 로 이러한 규칙이 있다는 걸 알 수 있다.
즉( n, k) = (n-1)(k) + (n-1)(k-1) 이다.
따라서 이러한 풀이가 가능하다.
#include <iostream>
using namespace std;
int dp[1001][1001];
int main()
{
ios_base::sync_with_stdio(false);
cout.tie(0); cin.tie(0);
int n, k;
cin >> n >> k;
for (int i = 0; i < n + 1; i++)
{
for (int j = 0; j < k + 1; j++)
{
if (i == j || j == 0)
dp[i][j] = 1;
else
dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - 1]) % 10007;
}
}
cout << dp[n][k];
}
저 파스칼 삼각형의 모양을 가진 알고리즘 문제도 여러번 본 것 같다.
알고 있으면 큰 도움이 될 것 같다.
'C++ 문제풀이 > 백준 문제풀이' 카테고리의 다른 글
[백준문제풀이] 1260. DFS와 BFS (0) | 2022.10.07 |
---|---|
[백준문제풀이 / 정수론 및 조합론] 11050. 이항 계수1 (0) | 2022.09.25 |
[백준문제풀이 / 정수론 및 조합론] 3036.링 (2) | 2022.09.24 |
[백준 문제풀이/정수론 및 조합론] 2981.검문 (0) | 2022.09.23 |
[백준 문제풀이 / 동적계획법] 1912.연속합 (2) | 2022.09.13 |