Stunning Garbanzo
open main menu
Part of series: PS

8984 BOJ

/ 2 min read

문제

접근

다이내믹 프로그래밍으로 해결하였다.

막대기들을 정렬한 후 각각의 막대기에 대하여 해당 막대기의 위 혹은 아래에서 시작하여 이전 막대기들만 사용하였을 때의 최대 거리를 dp 배열에 저장하는 방식으로 해결하였다. 주의해야 할 점은, 이전 막대기들 중 이어질 수 있는 막대기를 찾는 과정에서 시간 초과가 날 수 있다는 점이다. 매번 이전 막대기들을 전부 뒤적이면 O(n^2)의 시간 복잡도를 가지므로 좌표값을 바탕으로 해시맵을 구성해 해당 좌표값으로부터 시작하는 막대기로 이은 선 중 가장 긴 선의 길이를 저장하는 식으로 시간복잡도를 낮추어야 한다.

코드

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef const ll cll;

cll N = 1e5, TERM = 1e6;
ll n, term, dp[N][2] = {};
pll sticks[N];
map<ll, ll> remains[2];

int main(void) {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

  cin >> n >> term;
  for (ll i = 0, t, d; i < n; ++i) {
    cin >> t >> d;
    sticks[i] = {t, d};
  }
  sort(sticks, sticks + n);

  ll result = 0;
  for (ll i = 0, t, d, len; i < n; ++i) {
    tie(t, d) = sticks[i];
    dp[i][0] = dp[i][1] = len = abs(t - d) + term;

    dp[i][1] = max(dp[i][1], remains[0][t] + len);
    dp[i][0] = max(dp[i][0], remains[1][d] + len);

    remains[0][t] = max(remains[0][t], dp[i][0]);
    remains[1][d] = max(remains[1][d], dp[i][1]);

    result = max(result, dp[i][0]);
    result = max(result, dp[i][1]);
  }

  cout << result << "\n";

  return 0;
}