[백준 4811] 알약(Java)

최민길(Gale)·2023년 2월 3일
1

알고리즘

목록 보기
30/172

문제 링크 : https://www.acmicpc.net/problem/4811

이 문제는 dp 문제로 문제의 규칙성을 파악하면 풀 수 있습니다.

이 문제의 핵심은 dp 배열을 어떤 식으로 설정하는가 입니다. 이 문제는 dp 배열을 이차원 배열로서 dp[W : 한 조각을 꺼낸 날][H : 반 조각을 꺼낸 날] 로 설정하면 됩니다.

전체적인 로직은 다음과 같습니다.

  1. 현재 알약의 상태인 dp[N][0] 조건에서 시작해서 역순으로 진행한다.
  2. 알약 한 개가 멀쩡히 존재할 경우 현재 조건은 알약 한 개를 쪼개고 반 개를 추가한 조건과 같은 경우이다.
  3. 만약 알약 반 개가 하나 이상 존재하는 경우라면 한 개를 쪼개지 않고 반 개를 먹는 경우의 수를 더한다.
  4. W가 0, 즉 모든 알약을 다 쪼갰을 경우 쪼갠 알약 먹는 경우밖에 없으므로 1을 리턴한다.
  5. 현재 조건이 dp 배열에 저장되어 있다면 해당값을 리턴한다.

다음은 코드입니다.

import java.io.*;
import java.util.*;

public class Main{

    static int N;
    static long[][] dp = new long[31][31];

    static long eatPills(int w, int h){
        // 만약 현재 조건의 값이 dp 리스트에 저장되어있다면 해당값 리턴
        if(dp[w][h] != 0) return dp[w][h];

        // 만약 w가 0, 즉 모든 알약을 다 쪼갰을 경우 쪼갠 알약 먹는 경우밖에 없으므로 1 리턴
        if(w==0) return 1;

        // 알약 한 개가 멀쩡히 존재할 경우 현재 조건은 알약 한 개를 쪼개고 반 개를 추가한 조건과 같은 경우임
        dp[w][h] = eatPills(w-1,h+1);

        // 만약 알약 반 개가 하나 이상 존재하는 경우라면 한 개를 쪼개지 않고 반 개를 먹는 경우의 수를 추가
        if(h>0) dp[w][h] += eatPills(w,h-1);

        // 결과 리턴
        return dp[w][h];
    }

    public static void main(String[] args) throws Exception{
        StringBuilder sb = new StringBuilder();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        while (true){
            N = Integer.parseInt(br.readLine());
            if(N==0) break;

            // 현재 날짜에서부터 역순으로 찾아가기
            long res = eatPills(N,0);
            sb.append(res);
            sb.append("\n");
        }
        System.out.println(sb);
    }
}

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글

관련 채용 정보