일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 개인 프로젝트
- 10월
- C/C++
- 개인 프로젝트 - 런앤건
- 코딩 기초 트레이닝
- 단계별로 풀어보기
- 2022년
- 1월
- 7월
- 유니티 심화과정
- 코딩 테스트
- 골드메탈
- 프로그래머스
- 기초
- 백준
- 2023년
- 2025년
- 3월
- 5월
- 자료 구조
- 2024년
- 수학
- 입문
- 유니티
- 4월
- 2월
- c++
- 게임 엔진 공부
- 다이나믹 프로그래밍
- todolist
- Today
- Total
기록 보관소
[Baekjoon/백준] 11401번: 이항 계수 3(C/C++) 본문
단계별로 풀어보기 20단계(분할 정복) 5번 문제
https://www.acmicpc.net/step/20
분할 정복 단계
히스토그램에서 가장 큰 직사각형을 찾는 문제. (※인터넷에 널리 알려져 있는 풀이와 달리, 분할 정복 과정에서 어떠한 자료구조도 필요 없습니다.)
www.acmicpc.net
백준 11401번: 이항 계수 3
https://www.acmicpc.net/problem/11401
11401번: 이항 계수 3
자연수 \(N\)과 정수 \(K\)가 주어졌을 때 이항 계수 \(\binom{N}{K}\)를 1,000,000,007로 나눈 나머지를 구하는 프로그램을 작성하시오.
www.acmicpc.net
문제 설명
자연수 N과 정수 K가 주어졌을 때 이항 계수 nCk를 1,000,000,007로 나눈 나머지를 구하는 프로그램을 작성하시오.
입력과 출력
입력: 첫째 줄에 N과 K가 주어진다. (1 ≤ N ≤ 4,000,000, 0 ≤ K ≤ N)
출력: nCk를 1,000,000,007로 나눈 나머지를 출력한다.
접근 방법
이번 문제는 N과 K를 입력받아서 이항계수 nCk를 1,000,000,007로 나눈 나머지를 출력하는 문제다.
역시 수학에서 손 땐지 너무 오래되서 그런지 수학 문제는 너무 어렵다.. 예전에 풀어봤던 이항 계수 1, 2 문제들을 보면서 이를 기반으로 고민을 많이 해봤는데 잘 되지 않았다. 그래서 인터넷을 찾아서 이 블로그 글과 이 블로그 글을 참고해서 해결했다.
우선 이항 계수는 위 식들처럼 계산할 수 있다. 이는 예전에 풀어봤던 문제들로 인지하고 있었다. 다만 이항 계수 2번 문제처럼 진행할 경우 10억이 넘는 숫자를 계산해야해서 시간초과가 발생할 것이다. 그리고 정의를 사용하더라도 분수에서 나머지 연산을 하는 것은 분모가 0이 될 수 있으므로 불가능하다.
그래서 다른 방법을 찾아야한다. 여기서 '페르마의 소정리'를 활용한다. 이를 분모에 적용하면 아래 식과 같이 나오게 된다. 이를 활용해서 분할 정복을 하면서 문제를 풀면 된다.
코드
#include <iostream>
using namespace std;
long long int A = 1, B = 1;
long long int solve(long long int X) {
if (X == 0) return 1;
if (X % 2 == 1)
return B * solve(X - 1) % 1000000007;
long long int temp = solve(X / 2);
return (temp * temp) % 1000000007;
}
int main(int argc, char *argv[]) {
long long int N, K;
cin >> N >> K;
for (int i = N; i >= N - K + 1; i--) //N * (N - 1) * ... *(N - K + 1)
A = (A * i) % 1000000007;
for (int i = 1; i <= K; i++) //K!
B = (B * i) % 1000000007;
B = solve(1000000007 - 2); //K!^(p - 2)
cout << A * B % 1000000007 << endl;
return 0;
}
결과
'코딩 테스트 > 백준' 카테고리의 다른 글
[Baekjoon/백준] 10830번: 행렬 제곱(C/C++) (0) | 2022.05.08 |
---|---|
[Baekjoon/백준] 2740번: 행렬 곱셈(C/C++) (0) | 2022.05.07 |
[Baekjoon/백준] 1629번: 곱셈(C/C++) (0) | 2022.05.04 |
[Baekjoon/백준] 1780번: 종이의 개수(C/C++) (0) | 2022.04.29 |
[Baekjoon/백준] 1992번: 쿼드트리(C/C++) (0) | 2022.04.27 |