BOJ11570: 환상의 듀엣

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

  • 아름답게 풀려서 기분좋은 DP 문제
  • DP Index의 기준을 매번 갱신해주는 문제이다.
  • 단순하게 생각하면 3가지 상태가 필요하다.
    • X: 지금까지본 Index
    • LA: A 집합에 속한 마지막 Index
    • LB: B 집합에 속한 마지막 Index
  • 조금만 생각해보면 X는 LA나 LB 둘중 하나와 같다. 즉 아래 두개로 줄일수 있다.
    • X: 지금까지 본 Index
    • Lother: X를 포함하는 집합이 아닌 집합의 마지막 Index
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <bits/stdc++.h>
using namespace std;


int main() {
  int N;
  scanf("%d", &N);
  if (N <= 2) {
    cout << 0;
    return 0;
  }
  vector<int> arr(N+1);
  for(int i = 1; i <= N; i++)
    scanf("%d", &arr[i]);
  vector<vector<int>> dp(N+1, vector<int>(N+1, 1e9));
  dp[0][0] = dp[1][0] = dp[2][1] = 0;
  dp[2][0] = abs(arr[2] - arr[1]);
  for(int i = 3; i <= N; i++) {
    for(int j = 0; j < i-1; j++) {
      dp[i][j] = dp[i-1][j] + abs(arr[i] - arr[i-1]);
      if(j) dp[i][i-1] = min(dp[i][i-1], dp[i-1][j] + abs(arr[i] - arr[j]));
      else dp[i][i-1] = dp[i-1][0];
    }
  }
  int ans = 1e9;
  for(int i = 0; i < N; i++)
    ans = min(ans, dp[N][i]);
  cout << ans;
}