백준 4811 - 알약
Updated:
Java
4811 번 - 알약
문제
접근 방법
먼저 w와 h로 만들 수 있는 서로 다른 문자열의 개수를 구해보자.
DP[W][H]
를 큰 알약 W개와 작은 알약 H개로 만들 수 있는 서로 다른 문자열의 경우의 수이다.
만약 H가 0이고 W가 1부터 증가하면,
dp[1][0] = 1 -> 'W'
dp[2][0] = 1 -> 'WW'
...
dp[n][0] = 1 -> 'WWW ... WW'
가 된다.
W으로만 만들 수 있는 서로 다른 문자열은 하나 밖에 없기 때문이다.
그럼 H로만 만들 수 있는 문자열도 하나로 동일하다.
dp[0][1] = 1 -> 'H'
dp[0][2] = 1 -> 'HH'
...
dp[0][n] = 1 -> 'HHH ... HH'
만약 W와 H가 각각 1개씩일 때 만들 수 있는 서로다른 문자열은 무엇일까?
dp[1][1] = 2 -> 'WH', 'HW'이다.
그럼 W가 2, H가 1로 만들 수 있는 문자열은?
dp[2][1] = 3 -> 'WWH', 'WHW', 'HWW'
즉 위 패턴을 보면, ‘W’와 ‘H’로 표현할 수 있는 길이가 N인 문자열 = ‘W’와 ‘H’로 표현할 수 있는 길이가 N - 1인 문자열 + ‘W’ or ‘H’ 이다!
위 방식으로 dp[n][n]를 구하면 될 것 같지만, 문제의 제일 중요한 조건이있다.
처음에 반드시 한 조각 W
가 나와야 하므로, H가 제일 처음 나오는 문자열은 존재 할 수 없다.
따라서, 위 dp를 만드는 조건에서 H가 처음 나오는 값은 다 0으로 생각하여야한다.
dp[0][1] = 0
dp[0][2] = 0
...
dp[0][n] = 0
이에 H가 W보다 많은 경우는 반드시 H가 먼저 시작하게 되는 경우가 존재하므로 0이다.
코드
import java.util.*;
import java.io.*;
public class Main {
static int n, tc, result;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
long[][] dp;
while(true) {
n = stoi(br.readLine());
if(n == 0)
break;
dp = new long[31][31];
// w로만 만들어 지는 서로 다른 문자열의 개수는 1이다.
for(int i = 1; i <= 30; i++)
dp[i][0] = 1;
for(int i = 1; i <= 30; i++) {
for(int j = 1; j <= 30; j++) {
// 만약 H가 W보다 많은 경우는 존재 할 수 없다.
if(j > i)
break;
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
System.out.println(dp[n][n]);
}
br.close();
}
static int stoi(String str) {
return Integer.parseInt(str);
}
}
총평
후기
2개의 알파벳으로 만들 수 있는 서로 다른 문자열의 경우의 수를 구하는 것이 핵심인 문제였다.