Recommendations(1700/贪心/优队/排序)

题目:http://codeforces.com/contest/1315/problem/D
题意:给定n个数 a i a_i ,和对应位置上加1的代价 t i t_i ,求最小代价使得最终n个数互不相同。
1 < = n < = 2 e 5 , 1 < = a i < = 1 e 9 , 1 < = t i < = 1 e 5 1<=n<=2e5,1<=a_i<=1e9,1<=t_i<=1e5
题解:将按初始权值排序,用优队队列储存重复值,每次队列取数贪心地将最大代价留下。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 200010;
#define ll long long

int n;
struct node{
	int val,cost;
	bool operator <(const node &b) {
		return val < b.val;
	}
}a[maxn];
int main() {
	scanf("%d",&n);
	for(int i = 0;i < n;i++) scanf("%d",&a[i].val);
	for(int i = 0;i < n;i++) scanf("%d",&a[i].cost);
	priority_queue<int> q;
	sort(a,a+n);
	ll cur = 0,ans = 0;
	int val,x;
	for(int i = 0;i < n;i++) {
		//当队列中的数的val<当前val,集体前进一个,且留下代价最大的 
		while(!q.empty() && val < a[i].val) {
			x = q.top();q.pop();
			cur -= x;ans += cur;val++;
		}
		if(!q.empty()) {//非空时说明有相同的val
			q.push(a[i].cost);
			cur += a[i].cost;
		}else if(i+1<n && a[i+1].val == a[i].val){
			q.push(a[i].cost);
			cur += a[i].cost;
			val = a[i].val;//设置优队初始val 
		}
	}
	while(!q.empty()) {//集体前进,留下代价最大的 
		x = q.top();q.pop();
		cur -= x;ans += cur;
	}
	printf("%I64d\n",ans);
}
发布了152 篇原创文章 · 获赞 2 · 访问量 6455

猜你喜欢

转载自blog.csdn.net/weixin_43918473/article/details/104656322