Codeforces 1974G Money Buys Less Happiness Now

rizynvu發表於2024-05-21

考慮到有一種貪心的思路就是能選就選。
顯然這是錯的,因為可能存在後面更優的情況,即當 \(c_i > c_j(i < j)\) 時,選 \(j\) 肯定比選 \(i\) 更優,因為後面剩下的更多且中間也留下了一些。

於是考慮反悔貪心。
還是一樣的,如果能選就一定選上。
否則來說,考慮對於當前已經選了的中的最大值,如果當前值比最大值小,那麼將其替換掉即可。

但是似乎還漏了一部分,就是中間留下的那一部分,但能證明這部分肯定不優。
假設當前是第 \(i\) 個,替換掉的是第 \(j(j < i, c_i < c_j)\) 個。
對於當前已經選的數的總和 \(sum\),有 \(sum + c_i > ix\)
同時對於 \(k\in (j, i)\) 且沒被選的第 \(k\) 個,根據貪心策略肯定有 \(c_k > c_j\),那麼 \(k\) 肯定選不了。
所以不會出現這種情況。

時間複雜度 \(\mathcal{O}(m\log m)\)

#include<bits/stdc++.h>
inline void Main() {
   int m, x;
   scanf("%d%d", &m, &x);
   int tot = 0, cnt = 0;
   std::priority_queue<int> Q;
   for (int v; m--; tot += x) {
      scanf("%d", &v);
      if (tot >= v)
         tot -= v, cnt++, Q.push(v);
      else if (! Q.empty() && v < Q.top())
         tot += Q.top() - v, Q.pop(), Q.push(v);
   }
   printf("%d\n", cnt);
}
int main() {
   int T;
   scanf("%d", &T);
   while (T--) Main();
   return 0;
}

相關文章