풀이: 어떤 수가 마지막을 이루고 있는지를 확인한다
만약 1로 끝나는 경우라면 arr[i-1][2] + arr[i-1][3]인 2로 끝나는 것과 3으로 끝나는 값을 서로 더해주면 된다.
#include <iostream>
using namespace std;
int main() {
// 입력 출력 속도 향상을 위한 설정
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n;
// n값 입력 받기
cin >> n;
// 2차원 배열 선언 (최대 1000000까지 크기, 4개의 열)
// arr[i][1], arr[i][2], arr[i][3]은 각각 i를 1, 2, 3으로 나눈 경우의 값을 저장
// long long 자료형을 사용하여 큰 값을 처리할 수 있도록 설정
long long arr[1000001][4] = {0,};
// 초기값 설정: n이 1일 때, 1을 만드는 유일한 방법은 1을 사용하는 것
arr[1][1] = 1;
// n이 2일 때, 2를 만드는 유일한 방법은 2를 사용하는 것
arr[2][2] = 1;
// n이 3일 때, 1, 2, 3을 사용하는 방법이 모두 가능
arr[3][3] = 1;
arr[3][2] = 1;
arr[3][1] = 1;
// n이 4 이상일 때, i를 1, 2, 3의 조합으로 나누는 경우의 수 계산
for(int i = 4; i <= 1000000; i++) {
// i를 1로 나눈 경우는 i-1을 2 또는 3으로 나눈 경우의 수를 합한 것
arr[i][1] = arr[i-1][2] + arr[i-1][3];
// i를 2로 나눈 경우는 i-2를 1 또는 3으로 나눈 경우의 수를 합한 것
arr[i][2] = arr[i-2][3] + arr[i-2][1];
// i를 3으로 나눈 경우는 i-3을 1 또는 2로 나눈 경우의 수를 합한 것
arr[i][3] = arr[i-3][2] + arr[i-3][1];
// 각 경우의 수를 1000000009로 나눈 나머지로 저장하여 overflow 방지
arr[i][1] %= 1000000009;
arr[i][2] %= 1000000009;
arr[i][3] %= 1000000009;
}
// 테스트 케이스의 개수 n만큼 반복
for(int i = 0; i < n; i++) {
int t;
// 테스트 케이스에서 숫자 t 입력 받기
cin >> t;
// t를 1, 2, 3의 조합으로 나눈 모든 경우의 수 계산 후 출력
// 결과를 1000000009로 나눈 나머지를 출력
cout << (arr[t][1] + arr[t][2] + arr[t][3]) % 1000000009 << '\n';
}
}
'개발 > 알고리즘' 카테고리의 다른 글
mysql-connector-cpp in C++ 라이브러리 형변환 문제 (1) | 2024.11.28 |
---|---|
백준 2751 수 정렬하기 2) merge sort(합병정렬) 재귀, 간단한 코드, c++ (0) | 2024.11.28 |
11052 실버 1) 카드 구매하기 DP (0) | 2024.10.23 |
17087 실버 2 ) 숨바꼭질 6 - 유클리드 호제법 (0) | 2024.10.08 |
백준 실버 2 ) 10799 쇠막대기 stack (0) | 2024.09.19 |