小L打CF
Description
有 个 号,每场比赛他会使用一个账号,会得到一个 ,假设原 为 , 为 ,则 变为 。
会贪心地选择自己每一次使用的号,使得 每场之后 之和最大,请您在每一场比赛之后输出他的 之和,保留两位小数。
换句话说,每场之前,小 L 根据当前自己所有号 ,选出一个号参加比赛,以最大化这场之后他的 之和。下一场时,之前的选择都会被保留,即使换一种选择可能使下一场后 和更大,也不能更换之前的选择。
Input
第一行两个正整数 ,表示号的个数和比赛场数。
接下来一行 个整数,表示他每个号的 。
之后 行,每行 个整数,表示 的 。
Output
对于每一个询问,输出一个实数表示答案,。
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
对于 的数据, 。
对于 的数据, , 和 均为 之间的整数。
解题思路
假设某场选中的账号 为 ,则本场结束后,总 变化为 ,化简得 ,则最小化 的值,可以使得总和最大,因此用优先队列每次选中最小的 来操作即可。
#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;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18122175