IT 기획의 길

백준 15990번 1,2,3 더하기 5 [JAVA] 본문

알고리즘(백준)/DP

백준 15990번 1,2,3 더하기 5 [JAVA]

완벽하기 쉽지 않지만 완벽해지려고 노력해야 한다 2021. 1. 11. 13:58

문제

정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 3가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다. 단, 같은 수를 두 번 이상 연속해서 사용하면 안 된다.

  • 1+2+1
  • 1+3
  • 3+1

정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다. n은 양수이며 100,000보다 작거나 같다.

출력

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

 

 

 

 

이 문제는 어려워서 어제 풀다가 포기한 문제였다

쉬운 계단수, 이친수 문제를 풀고 오니까 좀 수월졌지만 처음에는 진짜 감을 잡지 못하였다

 

알고리즘 설계

 

1.  long [][]dp=new long[end][4]인 배열을 선언한다 (end=100001) 

행은 1~1000000까지의 수가 오는 자리 

열은 1,2,3  즉 마지막으로 더한수에 대한 정보이다 

 

ex) dp[20][3] -> 1,2,3의 합으로 20이 된 경우의 수중에 마지막으로 3을 더해서 20이 된 경우의 수 

 

2. 점화식을 만든다

dp[i][1] -> 숫자 i를 1,2,3의 합으로 나타낼수 있는 경우의 수 중에 마지막수를 1로 더한 경우 

()+1=i가 된다

()부분은 dp[i-1][2]+dp[i-1][3]이 된다

()부분은 숫자 i-1를 1,2,3의 합으로 나타낼수 있는 경우의 수중에 마지막수를 2,3으로 더한 경우

 

dp[i][2] -> 숫자 i를 1,2,3의 합으로 나타낼수 있는 경우의 수 중에 마지막수를 2로 더한 경우

()+2=i가 된다

()부분은 dp[i-2][1]+dp[i-2][3]이 된다

()부분은 숫자 i-2를 1,2,3의 합으로 나타낼수 있는 경우의 수중에 마지막수를 1,3으로 더한 경우

 

dp[i][3] -> 숫자 i를 1,2,3의 합으로 나타낼수 있는 경우의 수 중에 마지막수를 3으로 더한 경우

()+3=i가 된다

()부분은 dp[i-3][1]+dp[i-3][2]이 된다

()부분은 숫자 i-3를 1,2,3의 합으로 나타낼수 있는 경우의 수중에 마지막수를 1,2으로 더한 경우

 

단 

dp[i][1]을 구하는 점화식의 경우 i>1이여야 한다  마지막수로 1을 더해서 생긴 수가 1보다 작거나 같을수는 없으니까 

dp[i][2]을 구하는 점화식의 경우 i>2이여야 한다  마지막수로 2를 더해서 생긴 수가 2보다 작거나 같을수는 없으니까 

dp[i][3]을 구하는 점화식의 경우 i>3이여야 한다  마지막수로 3을 더해서 생긴 수가 3보다 작거나 같을수는 없으니까 

 

그래서 1~3까지의 수는 미리 초기화 시켜놓고 풀었다.

 

 

3. 문제에서 요구하는대로 1000000009로 나눠준다

1000000009으로 나눈 값이 저장될 배열이니까 dp배열을 long형으로 선언해준것이다

 

 

import java.util.*;
public class Main {
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        long mod= 1000000009;
        int end=100001;
        long [][]dp=new long[end][4];

        // 1,2,3에 의해 i<4인 경우는 미리 초기화 시켜놓는다
        dp[1][1]=1;
        dp[1][2]=0;
        dp[1][3]=0;
        dp[2][1]=0;
        dp[2][2]=1;
        dp[2][3]=0;
        dp[3][1]=1;
        dp[3][2]=1;
        dp[3][3]=1;
        for(int i=4;i<end;i++){
            for(int j=1;j<=3;j++){
                if(j==1 ){ //1. i>1
                    dp[i][1]=(dp[i-1][2]+dp[i-1][3])%mod;
                }
                else if(j==2 ){ //2. i>2
                    dp[i][2]=(dp[i-2][1]+dp[i-2][3])%mod;
                }
                else if(j==3 ){ //3. i>3
                    dp[i][3]=(dp[i-3][1]+dp[i-3][2])%mod;
                }
            }
        }


        int t=sc.nextInt();
        for(int i=0;i<t;i++){
            int n=sc.nextInt();
            System.out.println((dp[n][1]+dp[n][2]+dp[n][3])%mod);
        }
    }
}