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

BOJ 28068 I Am Knowledge

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

📝 문제 정보
#

🧐 관찰 및 접근
#

  • 지금 어떤 책을 읽을 수 있고, $a_k <= b_k$라면, 읽지 않을 이유가 없다.
  • 나머지 $a_k > b_k$들인 책들은 어차피 읽을수록 즐거움이 감소만 하므로, $a_k$가 큰거부터 차례대로 읽으면 되지 않을까? 어떻게 그리디하게 가야하지?
    • 두 책 $i, j$가 있다고 해보자.
    • 이때, 두 책을 $i \rightarrow j$로 읽기 위해선
      • $F \geq a_i$
      • $F - a_i + b_i \geq a_j \rightarrow F \geq a_i + a_j - b_i$
      • 따라서 $F \geq \max(a_i, a_i + a_j - b_i) = \text{Cost}_{i \rightarrow j}$
    • 같은 방식으로, $j \rightarrow i$로 읽기 위해선
      • $F \geq \max(a_j, a_i + a_j - b_j) = \text{Cost}_{j \rightarrow i}$
    • 이 때, $b_i \geq b_j$라고 가정하자.
      • $a_i < a_i + (a_j - b_j)$
      • $a_i + a_j - b_i \leq a_i + a_j - b_j$
      • 이 두 식이 성립하므로, 언제나 $\text{Cost}_{i \rightarrow j} \leq \text{Cost}_{j \rightarrow i}$
      • 따라서 $b$의 내림차순으로 정렬 후 그리디가 성립한다.

💻 풀이
#

  • 코드 (C++):
void solve(){
    int N; cin >> N;
    vector<pii> v1, v2;
    rep(i, 0, N){
        int a, b; cin >> a >> b;
        if(a <= b) v1.push_back({a, b});
        else v2.push_back({a, b});
    }
    sort(all(v1));
    sort(all(v2), [](pii &p1, pii &p2){
        return p1.second > p2.second;
    });
    ll cur = 0;
    for(auto &p: v1){
        if(cur < p.first){
            cout << 0;
            return;
        }
        cur -= p.first;
        cur += p.second;
    }
    for(auto &p: v2){
        if(cur < p.first){
            cout << 0;
            return;
        }
        cur -= p.first;
        cur += p.second;
    }
    cout << 1;
}
🔒

구현 코드 잠금

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

🛒 쿠팡 방문하고 코드 보기

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