문제풀이/백준oj

[백준OJ] 15991번 1, 2, 3 더하기 6 - Java

Hyeon-Uk 2023. 1. 2. 20:36
반응형

https://www.acmicpc.net/problem/15991

 

15991번: 1, 2, 3 더하기 6

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

www.acmicpc.net


풀이

DP를 이용해서 문제를 해결했습니다.

DP[N] = 조건에 맞춰서 N을 만드는 경우의 수 입니다.

 

먼저 차근차근 규칙을 찾아가봅시다

1 = 1

2 = 1+1 / 2

3 = 1+1+1 / 3

4 = 1+1+1+1 / 2+2

5 = 1+1+1+1+1 / 1+3+1

6 = 1+1+1+1+1+1 / 1+2+2+1 / 1+1+2+1+1 / 2+2+2 / 3+3

 

6을 기준으로 규칙을 살펴보면

1+(조건에 맞게 4를 만드는 경우)+1 => 1+(1+1+1+1)+1 / 1+(1+2+1)+1

2+(조건에 맞게 2를 만드는 경우)+2 => 2+(2)+2

3+(조건에 맞게 0을 만드는 경우)+3 => 3+(0)+3

로 정리를 할 수 있습니다.

 

N을 기준으로 규칙을 살펴보면

1+(조건에 맞게 N-2를 만드는 경우)+1 => DP[N-2]의 양옆에 1을 붙이는 경우

2+(조건에 맞게 N-4를 만드는 경우)+2 => DP[N-4]의 양옆에 2를 붙이는 경우

3+(조건에 맞게 N-6을 만드는 경우)+3 => DP[N-6]의 양옆에 3을 붙이는 경우

 

 

이 규칙에 맞춰서 점화식을 세워보면

DP[N] = DP[N-2] + DP[N-4] + DP[N-6] ; (단 각 인덱스가 음수가 나올 경우에는 0으로 대체)

 

시간복잡도

O(N)

 

코드

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        long[] dp = new long[100001];
        dp[0]=1;
        dp[1] = 1;//1
        dp[2] = 2;//1+1,2
        dp[3] = 2;//1+1+1,3

        for (int i = 4; i <= 100000; i++) {
            dp[i] = ((i - 2 >= 0 ? dp[i - 2] : 0) + (i - 4 >= 0 ? dp[i - 4] : 0) + (i - 6 >= 0 ? dp[i - 6] : 0)) % 1000000009;
        }

        int T = Integer.valueOf(br.readLine());
        while (T-- > 0) {
            int n = Integer.valueOf(br.readLine());
            sb.append(dp[n]).append("\n");
        }

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        bw.write(sb.toString());
        bw.flush();
    }
}
반응형