[Offer收割]编程练习赛88

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值