[JAVA] 백준 (골드5) 2240번 자두나무

AIR·2024년 12월 2일

코딩 테스트 문제 풀이

목록 보기
161/194

링크

https://www.acmicpc.net/problem/2240


문제 설명

정답률 38.672%

자두는 자두를 좋아한다. 그래서 집에 자두나무를 심어두고, 여기서 열리는 자두를 먹고는 한다. 하지만 자두는 키가 작아서 자두를 따먹지는 못하고, 자두가 떨어질 때까지 기다린 다음에 떨어지는 자두를 받아서 먹고는 한다. 자두를 잡을 때에는 자두가 허공에 있을 때 잡아야 하는데, 이는 자두가 말랑말랑하여 바닥에 떨어지면 못 먹을 정도로 뭉개지기 때문이다.

매 초마다, 두 개의 나무 중 하나의 나무에서 열매가 떨어지게 된다. 만약 열매가 떨어지는 순간, 자두가 그 나무의 아래에 서 있으면 자두는 그 열매를 받아먹을 수 있다. 두 개의 나무는 그다지 멀리 떨어져 있지 않기 때문에, 자두는 하나의 나무 아래에 서 있다가 다른 나무 아래로 빠르게(1초보다 훨씬 짧은 시간에) 움직일 수 있다. 하지만 자두는 체력이 그다지 좋지 못해서 많이 움직일 수는 없다.

자두는 T(1≤T≤1,000)초 동안 떨어지게 된다. 자두는 최대 W(1≤W≤30)번만 움직이고 싶어 한다. 매 초마다 어느 나무에서 자두가 떨어질지에 대한 정보가 주어졌을 때, 자두가 받을 수 있는 자두의 개수를 구해내는 프로그램을 작성하시오. 자두는 1번 자두나무 아래에 위치해 있다고 한다.


입력 예제

7 2
2
1
1
2
2
1
1

출력 예제

6

풀이

dp배열을 다음과 같이 정의한다.

dp[t][w]: t초까지 w번 이동했을 때 얻은 자두의 최대 개수

자두의 이동 여부에 따라 생각해야 하는데

  • 현재 위치에 그대로 있는 경우
int stay = dp[t - 1][w];
//현재 위치에서 자두를 받을 수 있으면 +1
if (trees[t] == now) {
    stay++;
}
  • 위치를 변경한 경우
int move = dp[t - 1][w - 1];
if (trees[t] == now) {
    move++;
}

위 두가지 경우를 비교하여 dp[t][w] 값을 갱신해나가면 된다.

dp[t][w] = Math.max(stay, move);

전체 코드

//백준
public class Main {

    public static void main(String[] args) throws IOException {

        System.setIn(new FileInputStream("src/input.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int T = Integer.parseInt(st.nextToken());
        int W = Integer.parseInt(st.nextToken());
        int[] trees = new int[T + 1];

        for (int i = 1; i <= T; i++) {
            trees[i] = Integer.parseInt(br.readLine());
        }

        //dp[t][w]: t초까지 w번 이동했을 때 얻은 자두의 최대 개수
        int[][] dp = new int[T + 1][W + 1];

        for (int t = 1; t <= T; t++) {
            for (int w = 0; w <= W; w++) {
                //현재 위치 (w가 홀수면 2번 나무)
                int now = (w % 2 == 0) ? 1 : 2;

                //현재 위치에 그대로 있는 경우
                int stay = dp[t - 1][w];
                //현재 위치에서 자두를 받을 수 있으면 +1
                if (trees[t] == now) {
                    stay++;
                }

                //이동 횟수가 0보다 클 때
                if (w > 0) {
                    //위치를 변경한 경우
                    int move = dp[t - 1][w - 1];
                    //현재 위치에서 자두를 받을 수 있으면 +1
                    if (trees[t] == now) {
                        move++;
                    }
                    //현재 위치에 그대로 있는 경우와 위치를 변경한 경우를 비교
                    dp[t][w] = Math.max(stay, move);
                } else {  //이동 횟수가 0일 때
                    dp[t][w] = stay;
                }
            }
        }

        Arrays.stream(dp[T])
                .max()
                .ifPresent(System.out::println);
    }
}
profile
백엔드

0개의 댓글