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]);
}
}
}
'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 |