본문 바로가기
PS/BOJ

[자바] 백준 24956 - 나는 정말 휘파람을 못 불어 (java)

by Nahwasa 2024. 2. 24.

문제 : boj24956

 

 

필요 알고리즘

  • DP (동적 계획법)
    • DP로 풀 수 있는 문제이다.

※ 제 코드에서 왜 main 함수에 로직을 직접 작성하지 않았는지, 왜 Scanner를 쓰지 않고 BufferedReader를 사용했는지 등에 대해서는 '자바로 백준 풀 때의 팁 및 주의점' 글을 참고해주세요. 백준을 자바로 풀어보려고 시작하시는 분이나, 백준에서 자바로 풀 때의 팁을 원하시는 분들도 보시는걸 추천드립니다.

 

 

풀이

  우선 'WHE'가 가능한 경우의 수를 찾는다고 생각해보자. 이 경우 매우 직관적으로 가능한데, 하나씩 문자를 살펴보면서 'W'라면 이전까지 나온 W의 수+1, 'H'라면 현재까지 'WH'가 가능했던 경우의 수 + 이전까지 나온 'W'의 수, 'E'라면 현재까지 'WHE'가 가능했던 경우의 수 + 이전까지 나온 'WH'가 가능했던 경우의 수를 해주면 된다. 문제는 'WHE'가 아니라 동일한 문자가 2개 포함된 'WHEE'를 찾아야 한다는 점이다.

 

  dp[n][x]를 우선 정의해보자. n은 현재 문자열에서 보고 있는 문자의 위치이다. dp[n][0]은 현재까지 'W'가 가능한 경우의 수, dp[n][1]은 현재까지 'WH'가 가능한 경우의 수, dp[n][2]는 현재까지 'WHE'가 가능한 경우의 수, dp[n][3]은 현재까지 'WHEE'가 가능한 경우의 수로 정의했다. 위와 동일하게, 현재 나온 문자가 뭐냐에 따라 어떻게 처리할지 생각해보면 된다.

 

1. 'W'

dp[n][0] = dp[n-1][0] + 1

: 이전까지 가능했던 'W'가 나오는 경우의 수가 1개 늘었을 뿐이다.

 

2. 'H'

dp[n][1] = dp[n-1][1] + dp[n-1][0]

: 이전까지 가능했던 'WH'가 나오는 경우의 수에다가, 현재 'H'가 추가될 것이므로 이전에 'W'가 나오는 경우의수가 전부 새로운 'H'에 의해 'WH'가 가능한 경우의 수에 더해지게 된다.

 

3. 'E'

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

: 이전까지 'WHEE'가 가능했던 경우의 수에서 뒤에 'E'가 붙음으로써 2배가 된다. 그리고 기존 'WHE'가 가능했던 경우의 수에 'E'가 붙음으로 그만큼 더해진다(+dp[n-1][2]).

 

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

: 이전까지 'WH'가 가능했던 경우의 수에 'E'를 붙여주는 경우이다.

 

 

  그리고, 잘 보면 전부 dp[n-1]의 동일 위치는 그대로 가져오는걸 볼 수 있다(dp[n][0] = dp[n-1][0]+1 처럼). 따라서 2차원으로 할 필요 없이 그냥 1차원 dp[x] 만 냅두어도 동일하게 처리 가능하다.

 

 

코드 : github

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

public class Main {
    private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in), 1 << 16);
    private static final int MOD = 1000000007;

    public static void main(String[] args) throws Exception {
        new Main().solution();
    }

    public void solution() throws Exception {
        int n = Integer.parseInt(br.readLine());
        String s = br.readLine();
        int[] dp = new int[4];
        for (int i = 0; i < n; i++) {
            switch (s.charAt(i)) {
                case 'W': dp[0]++; dp[0]%=MOD; break;
                case 'H': dp[1]+=dp[0]; dp[1]%=MOD; break;
                case 'E':
                    dp[3]*=2; dp[3]%=MOD;
                    dp[3]+=dp[2]; dp[3]%=MOD;
                    dp[2]+=dp[1]; dp[2]%=MOD;
                    break;
            }
        }
        System.out.println(dp[3]);
    }
}