Skip to main content
  1. Posts/
  2. Algorithm/

BOJ 14587 도미노 (Large)

·224 words·2 mins
Jiho Kim
Author
Jiho Kim
달려 또 달려

📝 문제 정보
#

🧐 관찰 및 접근
#

  • 전처리를 적당히 할 수 있을까?
    • 이분탐색을 좀 하면서 밀면서 하면, 특정 도미노를 한쪽으로 밀었을때 어디까지 넘어가는지 할 수 있나?
    • 아, min/max 세그먼트 트리로 되는거같다
  • 마지막은 그리디가 아니라 DP로 해야한다!
  • 아니근데 X가 정렬되어 주어지지 않는다;;;;; 그래도 구현이 막 어렵지 않은듯

💻 풀이
#

  • 코드 (C++):
void solve(){
    int N; cin >> N;
    vector<ll> X(N), H(N);
    
    vector<pll> dominos(N);
    rep(i, 0, N) cin >> dominos[i].first >> dominos[i].second;
    sort(all(dominos));
    rep(i, 0, N){
        X[i] = dominos[i].first;
        H[i] = dominos[i].second;
    }

    SegmentTreeMinMax ST_min(N), ST_max(N);
    
    // calc leftmost
    ST_min.set(0, 0);
    rep(i, 1, N){
        ll val = X[i] - H[i];
        auto idx = lower_bound(all(X), val) - X.begin();
        auto Q = ST_min.query(idx, i-1);
        ST_min.set(i, min((ll)i, ST_min.query(idx, i-1).first));
    }
    
    // calc rightmost
    ST_max.set(N-1, N-1);
    rrep(i, 0, N-1){
        ll val = X[i] + H[i];
        auto idx = upper_bound(all(X), val) - X.begin() - 1;
        auto Q = ST_min.query(i+1, idx);
        ST_max.set(i, max((ll)i, ST_max.query(i+1, idx).second));
    }

    vector<int> DP(N, 1e9);
    DP[0] = 1;
    DP[ST_max.get_val(0)] = 1;
    rep(i, 1, N){
        int lft = ST_min.get_val(i)-1;
        if(lft < 0) DP[i] = 1;
        else DP[i] = min(DP[i], DP[lft] + 1);

        int rht = ST_max.get_val(i);
        DP[rht] = min(DP[rht], DP[i-1] + 1);
    }
    cout << DP[N-1];
}
🔒

구현 코드 잠금

아래 쿠팡 링크를 방문하시면 코드가 공개됩니다.
광고 수익이 블로그 운영에 도움이 됩니다 🙏

🛒 쿠팡 방문하고 코드 보기

방문 후 잠금이 자동으로 해제됩니다