링크
https://www.acmicpc.net/problem/15988
정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 7가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다.
정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다. n은 양수이며 1,000,000보다 작거나 같다.
각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 1,000,000,009로 나눈 나머지를 출력한다.
3
4
7
10
7
44
274
정수 1을 1,2,3의 합으로 나타내는 방법
1
총 1개
--
정수 2를 1,2,3의 합으로 나타내는 방법
1+1
2
총 2개
--
정수 3을 1,2,3의 합으로 나타내는 방법
1+1+1
1+2
2+1
3
총 4개
--
정수 4를 1,2,3의 합으로 나타내는 방법
1+1+1+1
1+1+2
1+2+1
1+3
2+1+1
2+2
3+1
총 7개
--
정수 4를 1,2,3의 합으로 나타내는 방법을 살펴보자
먼저 맨 앞의 숫자가 1인 경우
뒤에서 3(4-1)이 나와야하므로 3을 나타내는 경우의 수, 즉 4가지가 존재한다.
맨 앞의 숫자가 2인 경우
뒤에서 2(4-2)가 나와야하므로 2를 나타내는 경우의 수, 즉 2가지가 존재한다.
맨 앞의 숫자가 3인 경우
뒤에서 1(4-3)이 나와야하므로 1을 나타내는 경우의 수, 즉 1가지가 존재한다.
위 3가지의 경우를 다 더하면 4를 1,2,3의 합으로 나타내는 방법의 수가 된다.
1+2+4 = 7
위 과정을 통해 점화식을 구해보면
dp[1] = 1, dp[2] = 2, dp[3] = 4
i가 4 이상일 때,
dp[i] = dp[i-1] + dp[i-2] + dp[i-3] 이 된다.
#include <stdio.h>
#include <stdlib.h>
#define mod 1000000009
#define ll long long
int main()
{
ll* dp; // dp 테이블 포인터
int n; // 각 테스트 케이스별 n값을 저장
int T; // 테스트 케이스의 개수
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
// 동적 할당
dp = (ll*)malloc((n + 3) * sizeof(ll));
// 초기값 설정
dp[1] = 1;
dp[2] = 2;
dp[3] = 4;
for (int i = 4; i <= n; i++)
dp[i] = (dp[i - 1] + dp[i - 2] + dp[i - 3]) % mod; // 구한 점화식 적용
printf("%d\n", dp[n]%mod);
free(dp); // 매 케이스마다 동적할당 후 메모리 해제
}
return 0;
}