牛客网暑假训练第五场——A gpa(01分数规划)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kuronekonano/article/details/81664368

链接:https://www.nowcoder.com/acm/contest/143/A
来源:牛客网

题目描述
Kanade selected n courses in the university. The academic credit of the i-th course is s[i] and the score of the i-th course is c[i].
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门功课,第i门功课有学分si,第i门功课考得了ci分,最终总分的计算公式为Σs[i]*c[i]/Σs[i],求删去k门功课后的最大总分。

01分数规划裸题,直接对计算公式推出不等式Σs[i]*c[i]/Σs[i]≥x,移项得到Σs[i]*c[i]-Σs[i]*x≥0
此处s[i]不能被提出抵消。直接二分取满足不等式条件的x并使其最大即可。

#include<bits/stdc++.h>///01分数规划
using namespace std;
const int maxn=1e5+7;
const double eqs=1e-6;
int n,k,s[maxn],c[maxn];
double mx[maxn];
bool judge(double x)///注意这里不等式两边的s[i]不能抵消
{
    for(int i=0;i<n;i++) mx[i]=s[i]*c[i]-x*s[i];///由题目给出不等式 Σ(s[i]*c[i])/ Σs[i] ≥ x可推出 Σ(s[i]*c[i])- x * Σs[i] ≥ 0,直接二分x的值即可
    sort(mx,mx+n);
    double ans=0;
    for(int i=n-1;i>k-1;i--)ans+=mx[i];///排序后对于课程可选前n-k个,求和即得到不等式的求和,与0比较,大于0则x合法,试探更大的x
    return ans>=0;
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++)scanf("%d",&s[i]);
    for(int i=0;i<n;i++)scanf("%d",&c[i]);
    double l=0,r=1e6+7;///二分范围时最大值1000*1000*100000/100000
    while(r-l>eqs)///二分答案
    {
        double mid=(l+r)/2;
        if(judge(mid))l=mid;
        else r=mid;
    }
    printf("%f\n",l);
}

猜你喜欢

转载自blog.csdn.net/kuronekonano/article/details/81664368