二分+最大化平均值 8.2牛客暑期多校训练营五 A

https://www.nowcoder.com/acm/contest/143/A

时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 262144K,其他语言524288KSpecial Judge, 64bit IO Format: %lld

题目描述

At the university where she attended, the final score of her is

Now she can delete at most k courses and she want to know what the highest final score that can get.

输入描述:

The first line has two positive integers n,k
​
The second line has n positive integers s[i]
​
The third line has n positive integers c[i]

输出描述:

Output the highest final score, your answer is correct if and only if the absolute error with the standard answer is no more than 10-5

示例1

输入

复制

3 1
1 2 3
3 2 1

输出

2.33333333333

说明

Delete the third course and the final score is 

备注:

1≤ n≤ 105
​
0≤ k < n
​
1≤ s[i],c[i] ≤ 103

题目大意:

给定 n( 1 <=n <=10^5 ) 门课以及它们的学分和绩点,定义总绩点是所有课的加权平均数,给定一个数 k, 你可以删除最多 k 门课,求你的总绩点最大能到多少

想法:

​ 想到了要把最后K个差的课程删掉。想了很久该怎么给课排序。然而WA了很多发。余老板说这个是最大化平均值,然后二分平均值就AC了。

思路:

参照标准题解:

考虑分数规划 二分答案,假设当前二分了一个值D,我们要判断是否存在一个方案使得总绩点>=D

化简过程:

(​

每个都si,ci已知,二分枚举D,满足第三式子,然后按​ 取前K小的课删掉就可以(因为课越少越好)。

余老板:

观察式子,把s[i]c[i]当作物品的价值,s[i]当作物品的重量,那么题目就变成了最大化平均值问题。二分枚举平均值x,判断能否选到(价值-重量*x)>=0的前n-k个物品。

AC代码:

余老板:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int MAXN = 1e5 + 5;
typedef long long LL;
LL n, k, s[MAXN], c[MAXN];
double y[MAXN];
 
bool check(double x) {
    for (int i = 0; i < n; ++i) y[i] = s[i] * c[i] - x * s[i];
    sort(y, y + n);
    double sum = 0;
    for (int i = k; i < n; ++i) sum += y[i];
    return sum >= 0;
}
 
int main() {
#ifndef ONLINE_JUDGE
    freopen("/home/lance/CLionProjects/code/nower_coder/Multi_University_Training_Contest/2018/five/input.txt", "r+",
            stdin);
//    freopen("data.out", "w+", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> k;
    for (int i = 0; i < n; ++i) cin >> s[i];
    for (int i = 0; i < n; ++i) cin >> c[i];
    double start = 0, end = INF, mid;
    for (int i = 0; i < 100; ++i) {
        mid = (start + end) / 2;
        if (check(mid)) start = mid;
        else end = mid;
    }
    cout.setf(ios::fixed);
    cout << setprecision(6) << end << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/KeeeepGO/article/details/81449252
今日推荐