문제 - https://www.acmicpc.net/problem/2449

 

2449번: 전구

입력의 첫 번째 줄에는 전구의 수를 나타내는 양의 정수 N과 전구가 표현할 수 있는 색의 수 K가 주어진다. 단, N은 1이상 200이하의 정수이며, K는 1이상 20이하의 정수이다. 두 번째 줄에는 N개 전

www.acmicpc.net

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

public class Main {

    static int N, K;
    static int[] C;
    static int[][] dp;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        C = new int[N+1];
        dp = new int[N][N]; // dp[i][j] : i부터 j까지 하나의 색으로 만드는데 필요한 최소 횟수
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            C[i] = Integer.parseInt(st.nextToken());
        }
        div(0, N-1); // 0부터 N-1까지 하나의 색으로 만드는데 최소횟수
        bw.write(dp[0][N-1]+"\n");

        bw.flush();
        bw.close();
        br.close();
    }
    static int div(int s, int e){
        if (s==e)
            return 0;
        if (dp[s][e]>0)
            return dp[s][e];
        int cnt = Integer.MAX_VALUE;
        int l, r;
        for (int i = s; i < e; i++) {
            l = div(s, i); // i번째의 왼쪽부분의 최솟값
            r = div(i+1, e); // i번째의 오른쪽부분의 최솟값
            cnt = Math.min(cnt, C[s]==C[i+1] ? l+r : l+r+1); // 색이 같으면 둘이 더하고, 다르면 한번을 추가한것을 더해서
        }
        return dp[s][e] = cnt; // 최솟값 갱신
    }
}

분할정복을 곁들인 DP문제다.

정말 점화식을 세우는 방법이 단 하나도 떠오르지 않았다...

생각하는게 너무 어렵다...

어떻게 공부해야할지 모르겠다..ㅠㅠ

'공부 > algorithm' 카테고리의 다른 글

BOJ 경사로(14890) - Java  (0) 2021.09.02
BOJ 상어 초등학교(21608) - Java  (0) 2021.08.31
BOJ 제단(5626) - Java  (0) 2021.08.25
BOJ 연구소(14502) - Java  (0) 2021.08.24
BOJ 컨베이어 벨트 위의 로봇(20055) - Java  (0) 2021.08.23

+ Recent posts