codeforces 1251E1/E2 Voting

Codeforces 1251E1/E2 Voting

題意

給你n個人,你需要讓這n個人全部給你投票。讓第i個人給你投票的方法有兩種:給他pi塊錢收買他,或者當前已經有mi個人爲你投票,他就會爲你免費投票。問最少花費多少錢

思路

首先不難發現,這道題可以貪心,在m相等的人裏優先給花費少的人錢。又因爲,如果我們讓某個m=i的人可以免費爲我們投票,則m<=i的其他人,都可以免費給我們投票。所以我們可以從大到小枚舉m,設爲M,更新ans,使得mi=M時,ans爲m>=M的人都已經爲我們投票時的最小花費。所以問題就轉換爲了如何更新ans。

注意我們這個枚舉有一個前提,就是對於每一個M取值,我們都假設了對於m<M的人,我們都已經獲得了他的選票,只不過這個ans的值沒有更新。所以對於每一個M的取值,我們設m=M的人數爲x,m>M中,我們打算白嫖的人的人數爲y,那麼根據假設,我們現在已經獲得了n-y個人的選票。那麼這x個人中,我們最多也可以白嫖n-y-M個人,那麼x中剩下的人,我們就需要去買。用優先隊列記錄一下,把p最小的那些人買了,ans就更新完成了。

代碼

#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define rush() int TT;scanf("%d",&TT);for(int TTT=1;TTT<=TT;TTT++)
const int maxn = 2e5+5;
vector<int> v[maxn];

int main() {
    rush() {
        int n,m,p;
        cin>>n;
        for(int i=0; i<=n; i++)
            v[i].clear();
        for(int i=0; i<n; i++) {
            cin>>m>>p;
            v[m].push_back(p);
        }
        priority_queue<int, vector<int>, greater<int>> q;
        ll ans = 0;
        for(int i=n-1; i>=1; i--) {
            for(int j=0; j<v[i].size(); j++)
                q.push(v[i][j]);
            while(q.size()>n-i) {
                ans+=q.top();
                q.pop();
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章