[백준] #9095 1, 2, 3 더하기 - JAVA

GAEUN·2025년 2월 12일

백준

목록 보기
2/14
post-thumbnail

❔ 문제

정수 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은 양수이며 11보다 작다.

출력

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

예제 입력1

3
4
7
10

예제 출력1

7
44
274

🔍 문제 풀이

이 문제는 점화식을 도출하여 DP로 해결할 수 있다. Bottom-up으로 작은 값부터 계산하여 점점 큰 값을 구하는 방식을 사용했다.

[점화식 도출]

dp[n]는 정수 n을 1, 2, 3의 합으로 나타내는 방법의 수로 정의

  • n = 1인 경우
    1
    dp[1] = 1

  • n = 2인 경우
    1 + 1
    2

    dp[2] = 2

  • n = 3인 경우
    1 + 1 + 1
    1 + 2
    2 + 1
    3

    dp[3] = 4

  • n = 4인 경우
    1 + 1 + 1 + 1
    1 + 2 + 1
    2 + 1 + 1
    3 + 1
    1 + 1 + 2
    2 + 2
    1 + 3
    dp[4] = dp[3] + dp[2] + dp[1] = 4 + 2 + 1 = 7

dp[4]일 때 dp[3]에 포함된 경우의 수와 dp[2]에 포함된 경우의 수, dp[1]에 포함된 경우의 수의 합과 같다.

즉, 점화식은 아래와 같다.

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


#### ❌ 첫 번째 제출(런타임 에러)
import java.io.*;
public class Main {

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

위 코드의 문제점

  • 입력받은 n이 1, 2, 3일 때, 배열 크기가 충분하지 않은 상태에서 dp[1], dp[2], dp[3]를 초기화하려고 시도하면 배열 범위를 벗어나면서 (ArrayIndexOutOfBoundsException) 런타임 에러가 발생
    ➡️ 예외 처리를 추가하여 n=1,2,3일 경우 바로 출력하도록 변경해야 함

☑️ 최종 코드

import java.io.*;
public class Main {

	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int t = Integer.parseInt(br.readLine());
		
		for(int tc = 0; tc < t; tc++) {
			int n = Integer.parseInt(br.readLine());
			int[] dp = new int[n+1];
			
			// 예외 처리 (n이 1, 2, 3일 경우)
			if (n == 1) {
                System.out.println(1);
                continue;
            } else if (n == 2) {
                System.out.println(2);
                continue;
            } else if (n == 3) {
                System.out.println(4);
                continue;
            }
			
			// DP 초기값 설정
			dp[1] = 1;
			dp[2] = 2;
			dp[3] = 4;
			
			// 점화식 적용하여 DP 배열 채우기
			for(int i = 4; i <= n; i++) {
				dp[i] = dp[i-1] + dp[i-2] + dp[i-3];
			}
			System.out.println(dp[n]);
		}
	}
}

0개의 댓글