정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 3가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다. 단, 같은 수를 두 번 이상 연속해서 사용하면 안 된다.
1+2+1
1+3
3+1
정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.
#include <iostream>
#include <cstring>
using namespace std;
static constexpr long long Mod = 1000000009LL;
static long long dp[100001][4];
static int T;
// 계산 과정에서 큰 수가 나올 수 있으므로 long long 자료형 사용, int 쓰면 틀린다.
long long solve(int num, int endCard) {
if (num <= 0) return 0; // 기저1 :: num이 0보다 작거나 같은 음수라면 경우의 수 0
if (num == endCard) return 1; // 기저2 :: num == endCard면 경우의 수 1
if (dp[num][endCard] > 0) return dp[num][endCard]; // 중복 연산 X
// 마지막 숫자가 1이면 그 이전 숫자는 2 또는 3이어야 한다.
if (endCard == 1) dp[num][endCard] = (solve(num - 1, 2) + solve(num - 1, 3)) % Mod;
else if (endCard == 2) dp[num][endCard] = (solve(num - 2, 1) + solve(num - 2, 3)) % Mod;
else if (endCard == 3) dp[num][endCard] = (solve(num - 3, 1) + solve(num - 3, 2)) % Mod;
return dp[num][endCard];
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> T;
memset(dp, 0, sizeof(dp));
while (T--) {
int n = 0; cin >> n;
cout << (solve(n, 1) + solve(n, 2) + solve(n, 3)) % Mod << '\n';
}
}