1947. 선물 전달 : https://www.acmicpc.net/problem/1947
1. 문제 파악하기
N명의 사람이 선물을 교환해야 합니다. 단, 다른 사람에게 꼭 자신의 선물을 건네야 합니다.
또한, N의 값이 1,000,000까지 커질 수 있으므로 long long int형을 사용해야 한다는 사실을 유념해야 합니다.
2. 문제 해결하기
DP[N]을 N명의 사람이 선물을 교환하는 방법이라고 정의하겠습니다.
만약 1번 사람이 K번 사람과 선물을 교환했다고 가정해봅시다. 그렇다면 위 상황은 (N-2)명의 사람들만 서로 선물을 교환해야 하는 상황으로 바뀌며, 이 때 방법의 수는 DP[N-2]가 됩니다. 그리고, 1번 사람이 선물을 교환할 K를 고르는 방법의 수는 (N-1)개이기 때문에 나올 수 있는 총 경우의 수는 (N-1)*DP[N-2] 가 됩니다.
만약 1번 사람이 K번 사람의 선물을 받고, K번 사람은 1번 사람이 아닌 다른 사람의 선물을 받았다고 가정해봅시다. 그렇다면 위 상황은 1을 제외한 (N-1)명의 사람이 (N-1)개의 선물을 교환한 상황으로 바뀌며, 이 때 방법의 수는 DP[N-1]가 됩니다. 그리고, 1번 사람이 선물을 받게 되는 방법의 수는 (N-1)개 이기 때문에 나올 수 있는 총 경우의 수는 (N-1)*DP[N-1] 가 됩니다.
위의 수식들을 활용해 점화식을 만들면 다음과 같으며, 이를 활용하여 문제를 해결할 수 있습니다.
>> DP[N] = (N-1)*DP[N-1] + (N-1)*DP[N-2]
3. 소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <stdio.h>
#define NMAX 1000010
#define MOD 1000000000
int N;
long long int dp[NMAX];
int main() {
scanf("%d", &N);
dp[0] = 1;
for(int i=2;i<=N;i++) dp[i] = ( (i-1)*dp[i-2]%MOD + (i-1)*dp[i-1]%MOD )%MOD;
printf("%lld", dp[N]);
}
|
cs |
4. 후기
위 점화식은 완전수열을 나타내는 점화식으로, 완전수열이란 서로 같은 숫자가 같은 위치에 있지 않는 수열을 의미합니다. 완전수열은 종종 출제되는 유형이니 알고 있을 필요가 있다고 생각합니다.
( 참고: https://j1w2k3.tistory.com/667 )
'문제 노트 > 백준' 카테고리의 다른 글
같은 탑( BOJ 1126 ) (0) | 2021.07.21 |
---|---|
자물쇠( BOJ 1514 ) (0) | 2021.07.19 |
블로그( BOJ 16157 ) (0) | 2021.07.06 |
248 게임( BOJ 12031 ) (0) | 2021.06.29 |
크리스마스 트리 꾸미기( BOJ 16468 ) (0) | 2021.06.21 |