Codeforce 1251 E. Voting (贪心,思维)

mac2024-03-21  26


题目大意: n 个人,每个人有两个属性 p , m p,m p,m,p 即 你收买这个人的价格, m m m 是你免费获得这个人的票你需要至少 m 票,问获得所有人的票至少要花多少钱。

m m m 分桶,倒过来做,计 p r e x pre_x prex m ≤ x m \leq x mx 的人数。 对于 m = i m = i m=i 的人,计算一下若 p r e i − 1 pre_{i - 1} prei1 的人都能获得,还需要买几个人才能获得全部的 m = i m = i m=i 的人的票。用 set 维护一个还没被收买的人,每次需要买时按价格从低到高买。


代码:

#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 2e5 + 10; int t,n,pre[maxn]; multiset<int> st; vector<int> g[maxn]; int main() { scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i = 1; i <= n; i++) { pre[i] = 0; int p,v;scanf("%d%d",&p,&v); g[p].push_back(v); } pre[0] = g[0].size(); st.clear(); for(int i = 1; i <= n; i++) { pre[i] = pre[i - 1] + g[i].size(); } ll ans = 0,cnt = 0; for(int i = n; i >= 1; i--) { for(auto it : g[i]) st.insert(it); int v = i - cnt - pre[i - 1]; while(v > 0 && st.size()) { ans += *st.begin(); cnt++,v--; st.erase(st.begin()); } } printf("%lld\n",ans); for(int i = 0; i <= n; i++) g[i].clear(); } return 0; }
最新回复(0)