题目2 : 增加得分
描述
小Hi在玩一款游戏,游戏中有N名玩家,每名玩家都有一个自己的当前分数A1, A2, ... AN。其中A1是小Hi的分数。
现在小Hi有2种方式提升自己的得分
1. 将自己的得分A1直接增加1分。该方式会消耗X枚金币
2. 从A2~AN中选则一名对手Ai,将自己的得分A1直接增加1分,对手Ai的得分减少1分。该方式会消耗Y枚金币。
小Hi的目标是成为N名玩家中分数最高的,也就是得分严格高于其他N-1名玩家。请你计算小Hi达成目标至少消耗多少枚金币。
输入
第一行包含3个整数N、X和Y。
第二行包含N个整数A1, A2, ... , AN。
1 <= N <= 100000
0 <= X, Y, Ai <= 100000
输出
一个整数代表答案。
样例输入
3 1 2 3 4 5
样例输出
3
思路:首先很明显可以想到可以直接算出只适用方案一需要多少花费,最大值减去a[1]加1乘x,然后考虑方案二肯定是从最大值考虑起a[1]加1最大值减去1算出执行多少次这个优先队列维护不难想到,难的是两个方案同时考虑解决方法是每执行一次方案二就算一次执行方案一要花费多少(具体看代码)
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define LL long long
using namespace std;
int main()
{
LL n,x,y;
priority_queue<LL>Q;
scanf("%lld%lld%lld",&n,&x,&y);
LL a;
scanf("%lld",&a);
for(LL i=2;i<=n;i++)
{
LL b;
scanf("%lld",&b);
Q.push(b);
}
if(a>Q.top())
{
printf("0\n");
return 0;
}
LL ans=(Q.top()-a+1)*x;
LL price=0;
while(a<=Q.top())
{
LL Max=Q.top();
Q.pop();
a++;
Max--;
price+=y;
Q.push(Max);//执行完方案二再次入队
if(a>Q.top())
{
ans=min(price,ans);
break;
}
LL cnt=price+(Q.top()-a+1)*x;//算出同时执行方案一和方案二的花费
ans=min(cnt,ans);
}
printf("%lld\n",ans);
return 0;
}