문제 - 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 |