[BOJ] 15990 "1, 2, 3 더하기 5" 문제 풀이 & 소스 코드 With C/C++

반응형
반응형

#INFO

난이도 : SIVLER3

알고리즘 유형 : DP(다이나믹 프로그래밍)
출처 : https://www.acmicpc.net/problem/15990

 

15990번: 1, 2, 3 더하기 5

각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 1,000,000,009로 나눈 나머지를 출력한다.

www.acmicpc.net


#SOLVE

전에 정리했던 9095 DP 문제에서 "1,2,3이 연속해서 나오면 안된다."는 조건이 추가되었다. 마찬가지로 마지막에 나오는 수에 집중하면 된다.

DP[n][i] = 숫자 n을 1, 2, 3의 합으로 나타내는 방법의 수 , i = 마지막 수 라고 가정한다. ( 1 <= i <= 3)

DP[n][1] = DP[n-1][2] + DP[n-1][3]

DP[n][2] = DP[n-2][1] + DP[n-2][3]

DP[n][3] = DP[n-3][1] + DP[n-3][2]

와 같이 나타낼 수 있다. 왜냐하면 만약 마지막의 수가 1이라면, 앞에 나오는 수는 1이 될 수 었으니, 2 혹은 3이 나와야 하기 때문이다.

따라서, n을 1, 2, 3의 합으로 만들 수 있는 방법의 가짓수는 DP[n][1] + DP[n][2] + DP[n][3] 이다.


#CODE

#include <iostream>
using namespace std;
long long dp[1000001][4];
const long long mod = 1000000009L;
const int limit = 100000;

int main(){
	// DP SOLVE
	for (int i=1; i<=limit; i++){
		if (i-1 >= 0){
			dp[i][1] = dp[i-1][2] + dp[i-1][3];
			if (i == 1){
				dp[i][1] = 1;
			}
		}
		
		if (i-2 >= 0){
			dp[i][2] = dp[i-2][1] + dp[i-2][3];
			if (i == 2){
					dp[i][2] = 1;
				}
		}
		
		if (i-3 >= 0){
			dp[i][3] = dp[i-3][1] + dp[i-3][2];
			if (i == 3){
				dp[i][3] = 1;
			}
		}
		
		dp[i][1] %= mod;
		dp[i][2] %= mod;
		dp[i][3] %= mod;
	}
	
	//PRINT
	int t;
	cin >> t;
	while(t--){
		int n;
		cin >> n;
		cout << (dp[n][1] + dp[n][2] + dp[n][3]) % mod << "\n";
	}

반응형

댓글

Designed by JB FACTORY