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

Codeforce 1251 E. Voting (贪心,思维)_第1张图片


题目大意: 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
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;
}

你可能感兴趣的:(思维,贪心)