[알고리즘 문제풀이] 백준 15988 1, 2, 3 더하기 3

고럭키·2021년 8월 10일
0

알고리즘 문제풀이

목록 보기
34/68

오늘 푼 문제는 백준 - 15988번 문제이다. 난이도는 실버2다 !

문제

정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 7가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다.

  • 1+1+1+1
  • 1+1+2
  • 1+2+1
  • 2+1+1
  • 2+2
  • 1+3
  • 3+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

풀이 방법

문제의 분류가 DP라는 것을 보자마자 쉽게 방법이 떠올랐다. 일단 문제에서 3까지만 사용한다는 것도 힌트가 되었다. ( 분류를 안 봤으면 이렇게 금방 못 풀었을 것 같기도 하다.. ! 이제 분류를 보지 않고 문제를 풀어봐야겠다 ! 진짜 못 풀겠을 때 힌트삼아 확인하기.. )

먼저 예제에 있는 7로 설명을 해보려고 한다. 7은 6+1이자, 5+2이자, 4+3이다. 그러므로 4, 5, 6을 만들 수 있는 경우의 수들이 구해져있다면, 각 경우들에 1, 2, 3을 더하면 되기 때문에, 각 경우의 수들의 합이 7의 경우의 수일 것이다. 이것이 곧 점화식 !!

해당 문제는 1-3을 이용해서 만들 수 있는 경우의 수를 구하는 것이므로, 초기값을 아래와 같이 3까지 구해둬야 한다.

  • R(1) = 1
  • R(2) = 2
  • R(3) = 4

위에 설명한 내용을 점화식으로 나타내면 아래와 같다.

  • R(n) = R(n-1) + R(n-2) + R(n-3) ( n은 3보다 큰 정수 )

이렇게 초기값과 점화식을 구하면 사실 DP 문제는 다 풀었다고 볼 수 있다 ~ 아래의 코드를 보면 된다 ~

또 이 문제에서 주의해야 할 것은, 문제에서 1,000,000,009로 나눈 값을 출력하라는 것 부터 힌트가 되지만, 각 경우의 수들이 int 범위를 넘어갈 수 있다. 그래서 점화식 결과 값을 저장하는 배열은 long 타입으로 해주었고, 저장할 때 Mod 연산을 수행한 후 저장해주었다 ~~

코드

import java.io.*;
import java.util.*;

public class Main {
    static class Solution{
        private static int MAX = 1000000;
        private static int MOD = 1000000009;
        private long[] results;

        Solution(){
            results = new long[MAX+1];
            Arrays.fill(results, -1);
            results[1] = 1;
            results[2] = 2;
            results[3] = 4;
        }

        void init(){
            for(int i=4; i<=MAX; i++){
                results[i] = (results[i-1]+results[i-2]+results[i-3])%MOD;
            }
        }

        long solution(int n){
            return results[n];
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // reader
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); // writer

        int n = Integer.parseInt(br.readLine());
        Solution solution = new Solution();
        solution.init();
        for(int i=0; i<n; i++){
            bw.write(solution.solution(Integer.parseInt(br.readLine())) + "\n");
        }

        bw.flush(); // flush
        bw.close(); // close
        br.close(); // close
    }
}

0개의 댓글