哈理工第八届校团队赛H刘禅的课程

题意:

Description

刘禅对学习的态度让太傅操碎了心。刘禅有n种课程要学习(礼、乐、射、御、书、数等等),每个课程有对应的重要程度s[i],刘禅估计了一下,机智的他算出了每个课程他最后能得到的分数c[i], 太傅给出了他最终成绩的计算公式:

在这里插入图片描述

现在他可以推迟k门课程,使得他剩下的n-k门课程的最终成绩尽量高,因为这样父皇才会让他出宫玩耍。机智的刘禅已经算出了答案,不过他想考考你。输出最高的不少于n-k门课程的最终成绩。

Input

多组数据,请读入到文件末尾(数据组数不超过10)第一行两个非负整数n, k(1≤ n≤ 1e5 , 0≤ k < n) 第二行n个正整数s[i] 第三行n个正整数c[i]1<=s[i],c[i]<=1000

Output

一个实数,四舍五入保留6位小数

Sample Input

3 1

1 2 3

3 2 1

Sample Output

2.333333

Hint

去掉最后一门课程即可。

(22+31)/(2+1)=7/3

思路:

​ 01分数规划的裸题,利用二分找结果ans,会得到si✖️ci/ si = ans ,只要贪心求的前n - k大的si✖️ci - ans✖️si的和,大于等于0返回1,否则返回0

代码:

#include <stdio.h>
#include <algorithm>
using namespace std;

int a[100005], b[100005];
int n, k;
double t[100005];

bool whd(double A, double B) {
    return A > B;
}

bool zcy(double val) {
    double sum = 0;
    for (int i = 0; i < n; i++) {
        t[i] = a[i] - val * b[i];
    }
    sort(t, t + n, whd);
    for (int i = 0; i < n - k; i++) {
        sum += t[i];
    }
    if (sum >= 0) return 1;
    return 0;
}

int main() {
    while (scanf("%d%d", &n, &k) == 2) {
        double minn = 0, maxx= 0;
        for (int i = 0; i < n; i++) {
            scanf("%d", &b[i]);
        }
        for (int i = 0; i < n; i++) {
            scanf("%d", &a[i]);
            a[i] = a[i] * b[i];
            if (maxx < a[i]) {
                maxx = a[i];
            }
        }
        double mid;
        for (int i = 0; i < 80; i++) {
            mid = (minn + maxx) / 2;
            if (zcy(mid)) minn = mid;
            else maxx = mid;
        }
        printf("%.6f\n", mid);
    }
    return 0;
}

转载请注明出处!!!

如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值