zoukankan      html  css  js  c++  java
  • [POJ2976] Dropping tests

    传送门:>Here<

    题意:给出长度相等的数组a和b,定义他们的和为$dfrac{a_1+a_2+...+a_n}{b_1+b_2+...+b_n}$。现在可以舍弃k对元素(一对即$a[i]和b[i]$),问最大的和是多少?

    解题思路

    01分数规划入门题(并没有学过,看到hy大佬在刷因此也去学了下)

    问题可以转化为数组中的每个元素选或不选,也就可以认为每一个元素都乘上一个$x[i], x[i] ∈ {0, 1}$

    因此问题可以转化为$ans = dfrac{sumlimits_{i = 1}^{n}a[i] * x[i]}{sumlimits_{i = 1}^{n}b[i] * x[i]}$

    将除法转化为加法$sumlimits_{i = 1}^{n}a[i] * x[i] - ans * sumlimits_{i = 1}^{n}b[i] * x[i] = 0$

    合并得$sumlimits_{i = 1}^{n}(a[i]-ans*b[i])*x[i] = 0$

    当$x$数组的取值确定时,可以发现函数$f(r) = sumlimits_{i = 1}^{n}(a[i]-r*b[i])*x[i]$是减函数,因此可以二分$r$。当前取到的$r$能够满足$sumlimits_{i = 1}^{n}(a[i]-r*b[i])*x[i] geq 0$即为可行,为了满足此条件,肯定要让选择的那些元素的和越大越好,因此可以建立数组$d[i] = a[i]-r*b[i]$并排序,选择最大的加起来验证是否大于等于0.

    Code

    long long

    /*By DennyQi 2018.8.12*/
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <algorithm>
    #define  r  read()
    #define  Max(a,b)  (((a)>(b)) ? (a) : (b))
    #define  Min(a,b)  (((a)<(b)) ? (a) : (b))
    using namespace std;
    typedef long long ll;
    #define int long long
    const int MAXN = 10010;
    const int MAXM = 27010;
    const int INF = 1061109567;
    inline int read(){
        int x = 0; int w = 1; register int c = getchar();
        while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
        if(c == '-') w = -1, c = getchar();
        while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar(); return x * w;
    }
    struct Score{
        int idx; double sc;
    }s[MAXN];
    int N,K;
    int a[MAXN],b[MAXN];
    double L,R,Mid,d[MAXN];
    inline bool comp(const Score& a, const Score& b){
        return a.sc < b.sc;
    }
    inline bool judge(double _r){
        for(int i = 1; i <= N; ++i){
            d[i] = (double)((double)(a[i]) - (double)(1.0*_r*b[i]));
        }
        sort(d+1,d+N+1);
        double res = 0.0;
        for(int i = N; i > K; --i){
            res += d[i];
        }
        return res >= 0.0;
    }
    #undef int
    int main(){
    #define int long long
        for(;;){
            N = r, K = r;
            if(!N && !K) break;
            for(int i = 1; i <= N; ++i) a[i] = r;
            for(int i = 1; i <= N; ++i) b[i] = r;
            L = 0.000, R = 9999999999.999;
            while(R - L >= 1e-8){
                Mid = (L + R) / 2.000;
                if(judge(Mid)){
                    L = Mid;
                }
                else{
                    R = Mid;
                }
            }
            for(int i = 1; i <= N; ++i){
                s[i] = (Score){i, (double)((double)(a[i]) - (double)(1.0*L*b[i]))};
            }
            sort(s+1,s+N+1,comp);
            int fz=0,fm=0;
            for(int i = N; i > K; --i){
                fz += a[s[i].idx];
                fm += b[s[i].idx];
            }
            double rs = (double)fz/(double)fm;
            printf("%.0f
    ", rs * 100);
        }
        return 0;
    }
  • 相关阅读:
    决战72hours
    学习中的十七条建议
    数学建模终结篇
    数学建模(7)建模开始
    ASP升级程序
    为blog挑选logo
    Mysql源代码分析系列(4): 主要调用流程(续)转载
    AS学习步骤
    什么是敏捷软件测试[转]
    Mysql源代码分析(6): Plugin架构介绍(续)转载
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9462816.html
Copyright © 2011-2022 走看看