小L打CF

Description

L小 LnnCFCF 号,每场比赛他会使用一个账号,会得到一个 PerformancePerformance ,假设原 RatingRatingxxPerformancePerformanceyy ,则 RatingRating 变为 (x+y)/2(x+y)/2 ​。

L小 L 会贪心地选择自己每一次使用的号,使得 每场之后 CFRatingCF Rating 之和最大,请您在每一场比赛之后输出他的 RatingRating 之和,保留两位小数。

换句话说,每场之前,小 L 根据当前自己所有号 RatingRating ,选出一个号参加比赛,以最大化这场之后他的 RatingRating 之和。下一场时,之前的选择都会被保留,即使换一种选择可能使下一场后 RatingRating 和更大,也不能更换之前的选择。

Input

第一行两个正整数 n,mn,m ,表示号的个数和比赛场数。

接下来一行 nn 个整数,表示他每个号的 RatingRating

之后 mm 行,每行 11 个整数,表示 L小 LPerformancePerformance

Output

对于每一个询问,输出一个实数表示答案,保留两位小数{\color{Red}保留两位小数}

Sample Input

5 5
2000 2100 2200 2300 2350
1900
1500
2200
2700
2000

Sample Output

10900.00
10675.00
10912.50
11281.25
11231.25

HINT

对于 30 %30 \ \% 的数据, n,m1000n,m≤1000

对于 100 %100 \ \% 的数据, 1n,m1051≤n,m≤10^5 , RatingRatingPerformancePerformance 均为 11051∼105 之间的整数。

解题思路

假设某场选中的账号 ratingratingxx ,则本场结束后,总 ratingrating 变化为 sumx+x+y/2sum-x+(x+y)/2,化简得 sumx/2+y/2sum-x/2+y/2 ,则最小化 x/2x/2 的值,可以使得总和最大,因此用优先队列每次选中最小的 ratingrating 来操作即可。

AC codeAC \ code

#include <bits/stdc++.h>
using namespace std;
struct abc
{
    double a = 0.0;
    bool operator<(const abc b) const
    {
        return b.a < a;
    }
    abc(double b)
    {
        a = b;
    }
};
priority_queue<abc> q;
int n, m;
double a, rating, ans;
signed main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i)
    {
        scanf("%lf", &a);
        ans += a;
        q.push((abc)a);
    }
    for (int i = 1; i <= m; ++i)
    {
        abc op = q.top();
        scanf("%lf", &a);
        rating = (double)(op.a + a) / 2;
        ans = ans - op.a + rating;
        q.pop();
        q.push((abc)rating);
        printf("%.2lf\n", ans);
    }
    return 0;
}
posted @ 2021-06-22 21:52  蒟蒻orz  阅读(4)  评论(0编辑  收藏  举报  来源