View

 

알고리즘 분류 : DP

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

 

 


 

정수 n을 1, 2, 3의 합으로 표현하는 방법의 수를 구하는 문제이다.

각각의 경우에서 숫자는 1, 2, 3을 한 번에 하나씩만 더해 나가며 만들 수 있다.

여기서 주의할 점은 순서만 다르고 합을 이루고 있는 요소가 같은 경우는 카운트에서 제외해야한다.

 

 일단 n=1, 2, 3일 때를 살펴보자.

 

n=1 일 때,

1=1

경우의 수는 1가지이다.

 

n=2일 때

2=1+1

2=2

경우의 수는 2가지이다.

 

n=3일 때,

3=1+1+1

3=1+2

3=3

경우의 수는 3가지이다.

 

얼핏 보면, n=3일 때를 보면 n=2일 때에서 +1을 붙인 경우, n=1일 때에서 +2을 붙인 경우, n=0일 때에서 +3을 붙인 경우가 보이는 것을 알 수 있다.

즉, 이렇게 표현할 수 있겠다.

 

dp[1][1]=1 => 숫자 1을 마지막에 1을 더해서 만드는 경우의 수
dp[2][1]=1 => 숫자 2를 마지막에 1을 더해서 만드는 경우의 수
dp[2][2]=1 => 숫자 2를 마지막에 2를 더해서 만드는 경우의 수
dp[3][1]=1 => 숫자 3을 마지막에 1을 더해서 만드는 경우의 수
dp[3][2]=1 => 숫자 3을 마지막에 2를 더해서 만드는 경우의 수
dp[3][3]=1 => 숫자 3을 마지막에 3을 더해서 만드는 경우의 수

 

여기서 n=4일 때를 살펴보면,
4=1+1+1+1 => dp[3][1] 에다 1을 붙임 => dp[4][1]=dp[3][1] 


4=1+1+2 => dp[2][1]  에다 2를 붙임 
4=2+2 => dp[2][2] 에다 2를 붙임 => dp[4][2] = dp[2][1] + dp[2][2]


4=1+3 => dp[1][1] 에다 3을 붙임 => ?

 

일단 이 규칙대로라면 dp[i][1] 은 무조건 1이 되고 dp[i][2] 는 i-2 를 만드는데 생긴 경우의 수들에 2를 더한듯 보인다.

그렇다면 이 생각 그대로 dp[i][3] 은 i-3을 만드는 데 생긴 경우의 수들에 3을 더한게 되지 않을까?

 

조금 애매하다. n=6일 때를 보자.

 

n=6
6=1+1+1+1+1+1

 

6=1+1+1+1+2

6=1+1+2+2

6=1+3+2

6=2+2+2

 

6=1+1+1+3

6=1+2+3

6=3+3 

 

dp[6-3]의 경우의 수들은 dp[3][1], dp[3][2], dp[3][3]이 있었고, 각각 1+1+1 , 1+2 , 3  이 있었다.

dp[3]의 경우의 수들에 +3을 붙인 게 맞았다!

 

즉 점화식은 다음과 같다.

 

dp[i][1]=dp[i-1][1]

dp[i][2]=dp[i-2][1]+dp[i-2][2]

dp[i][3]=dp[i-3][1]+dp[i-3][2]+dp[i-3][3]

 

따라서 구하고자 하는 최종 답은 dp[n][1]+dp[n][2]+dp[n][3] 이 되겠다.

 


 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws IOException {
        int t = Integer.parseInt(br.readLine());
        while(t-->0){
            int n=Integer.parseInt(br.readLine());
            int[][] dp=new int[n+11][4];
            dp[1][1]=1;
            dp[2][1]=dp[2][2]=1;
            dp[3][1]=dp[3][2]=dp[3][3]=1;
            
            for(int i=4;i<=n;i++){
                dp[i][1]=dp[i-1][1];
                dp[i][2]=dp[i-2][1]+dp[i-2][2];
                dp[i][3]=dp[i-3][1]+dp[i-3][2]+dp[i-3][3];
            }
            
            System.out.println(dp[n][1]+dp[n][2]+dp[n][3]);
        }
    }
}

 

 

 

 

 

 

 

 

 

 

728x90

'Problem Solving > Baekjoon' 카테고리의 다른 글

[백준] 21609: 상어 중학교 [Java]  (0) 2024.10.17
[백준] 19585: 전설 [Java]  (0) 2024.10.10
[백준] 9202: Boggle [Java]  (4) 2024.10.09
[백준] 28422: XOR 카드 게임  (0) 2024.04.08
[백준] 1149번: RGB거리 [C++]  (0) 2023.10.02
Share Link
reply
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31