Atcoder beginner contest 127D Integer Cards

https://atcoder.jp/contests/abc127/tasks/abc127_d
题意:有n个数字,m次操作,每次操作可以吧最多Bi个数字值替换成Ci,找出操作后最大可能的数字和。
思路:首先可以发现可以通过巧妙的选择方法,使2次操作较换位置后结果依然最大。那么先把操作按Ci从大到小排序,每次枚举i找有几个数满足它们的值都满足比Ci小。若有k个数满足,k>Bi时,找最小的Bi个的值转成Ci;k<=Bi时,把那k个数的值转成Ci,退出(更改完后一定满足所有a值都不小于Ci,而Ci+1<=Ci,所有之后的k值一定是0,不需要再更改了)。a的值可以用muntiset储存,找最小和加入最新都方便。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define pii pair
#define mp make_pair
#define fi first
#define se second
#define inf 0x7fffffff
using namespace std;
const int maxn=1e5+10;
pii b[maxn];
multiset<int> s;
ll sum()
{
	ll su=0;
	for(__typeof(s.begin()) it=s.begin();it!=s.end();it++)
	{
		su+=*it;
	}
	return su;
}
int main()
{
	int i,j,k,n,m,x,y;
	scanf("%d%d",&n,&m);
	for(i=0;i<n;i++)
	{
		scanf("%d",&y);
		s.insert(y);
	}
	for(i=0;i<m;i++)
	{
		scanf("%d%d",&b[i].se,&b[i].fi);
		b[i].fi=-b[i].fi;
	}
	sort(b,b+m);
	for(i=0;i<m;i++)
	{
		b[i].fi=-b[i].fi;
	}
	x=0;
	for(i=0;i<m;i++)
	{
		for(j=0;j<b[i].se;j++)
		{
			if(x>n||*(s.begin())>=b[i].fi)
			{
				goto en;
			}
			s.erase(s.begin());
			s.insert(b[i].fi);
			x++;
		}
	}
	en:;
	printf("%lld",sum());
	return 0;
}

你可能感兴趣的:(atcoder)