zoukankan      html  css  js  c++  java
  • 01分数规划牛客网 入门题

    链接: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 frac{2*2+3*1}{2+1}=frac{7}{3}

    备注:

    1≤ n≤ 105

    0≤ k < n

    1≤ s[i],c[i] ≤ 103

    题意:给你两个数组, s[i] , c[i] ,再给你一个式子时累加求和的相比求最大值的式子,同时你最多可以再其中删去 K 个字母,问最终最大收益是多少?

    思路分析 : 经典的 01分数规划问题,最优的结果一定是去掉越多的值越优,想一想就知道为什么了

    代码示例 :

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn = 1e6+5;
    const int mod = 1e9+7;
    const double eps = 1e-9;
    const double pi = acos(-1.0);
    const int inf = 0x3f3f3f3f;
    
    int n, k;
    double s[maxn], c[maxn];
    double a[maxn];
    
    bool check(double x){
        for(int i = 1; i <= n; i++){
            a[i] = (c[i]-x)*s[i];
        }    
        sort(a+1, a+1+n);
        
        double sum=0;
        for(int i = k+1; i <= n; i++){
            sum += a[i];
        }
        //printf("*** %lf
    ", sum);
        if (sum > 0) return true;
        return false; 
    }
    
    int main() {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        cin >> n >> k;
        
        for(int i = 1; i <= n; i++) {
            scanf("%lf", &s[i]);
        }    
        for(int i = 1; i <= n; i++) {
            scanf("%lf", &c[i]);
        }
        double l = 0, r = 1000.0;
        for(int i = 1; i <= 50; i++){
            double mid = (l+r)/2;
            if (check(mid)) l = mid;
            else r = mid;
        }
        printf("%.11lf
    ", l);
        return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    在线程中使用OpenFileDialog
    Log4net附加
    SQL表间列根据条件复制(赋值)
    DataGridView使用
    Latex使用总结及备忘
    Windows获取文件状态
    TabControl取消首次定位焦点
    C#跨线程调用
    电子词典的查寻程序,发送和接收应答程序
    电子词典的相关子函数db.c程序
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/9416638.html
Copyright © 2011-2022 走看看