Bailian4145 放弃考试 POJ2976 ZOJ3068 Dropping tests【二分法+01分数规划】

4145:放弃考试
总时间限制: 1000ms 内存限制: 65536kB
描述
在一门课程中,一共有n场考试。假如你在i场考试中可以答对bi道题中的ai道,那么你的累计平均分定义为:100·Σai/Σbi。已知你这i场考试的答题情况,并且允许你放弃其中的k场考试,请你确定你最高能够得到多少的累计平均分。

假设该课程一共有3门考试,你的答题情况为5/5,0/1和2/6。如果你每门都参加,你的累计平均分为100·(5+0+2)/(5+1+6)= 50分。如果你放弃第3场考试,你的累计平均分则提高到了100·(5+0)/(5+1)= 83.33 ≈ 83分。

输入
有多组测试数据,每组测试数据包括3行。
每组测试数据第一行有两个数n和k,接下来一行有n个数ai,最后一行n个数bi。
(1 ≤ k < n ≤ 1000) (1 ≤ ai ≤ bi ≤ 1, 000, 000, 000)。
输入的最后一行为0 0,不作处理。
输出
输出最高的累计平均分。(四舍五入到整数)
样例输入
3 1
5 0 2
5 1 6
4 2
1 2 7 9
5 6 7 9
0 0
样例输出
83
100

来源
http://poj.org/problem?id=2976

问题链接Bailian4145 放弃考试 POJ2976 ZOJ3068 Dropping tests
问题简述:给定n和k,有n场考试,给出每场答对的题数a和这场一共有几道题b,计算去掉k场考试后,公式100·Σai/Σbi的最大值。
问题分析
    01分数规划问题:给定价值a[i]和代价b[i],选举n-k个物品,使得总价值/总代价最大。那么算出Σai-xΣbi,去掉k个最小的即可(贪心法)。
    需要注意,上式中,因为Σai/Σbi>x相当于Σai-xΣbi>0。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* Bailian4145 放弃考试 POJ2976 ZOJ3068 Dropping tests */

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;

const double EPS = 1e-4;
const int N = 1000;
int n, k, a[N], b[N];
double y[N];

bool judge(double x) {
    for(int i = 0; i < n; i++) y[i] = a[i] - x * b[i];

    sort(y, y + n);

    double sum = 0;
    for(int i = n - 1; i >= k; i--) sum += y[i];

    return sum >= 0;
}

double bs()
{
    double left = 0, right = 1, mid;
    while(right - left > EPS) {
        mid = left + (right - left) / 2;
        if(judge(mid)) left = mid;
        else right = mid;
    }
    return mid * 100;
}

int main()
{
    while(~scanf("%d%d", &n, &k) && (n || k)) {
        for(int i = 0; i < n; i++) scanf("%d", &a[i]);
        for(int i = 0; i < n; i++) scanf("%d", &b[i]);

        printf("%.0f\n", bs());
    }

    return 0;
}
©️2020 CSDN 皮肤主题: 代码科技 设计师: Amelia_0503 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值