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;
    }
  • 相关阅读:
    ACM ICPC 2008–2009 NEERC MSC A, B, C, G, L
    POJ 1088 滑雪 DP
    UVA 11584 最短回文串划分 DP
    POJ 2531 Network Saboteur DFS+剪枝
    UVa 10739 String to Palindrome 字符串dp
    UVa 11151 Longest Palindrome 字符串dp
    UVa 10154 Weights and Measures dp 降维
    UVa 10271 Chopsticks dp
    UVa 10617 Again Palindrome 字符串dp
    UVa 10651 Pebble Solitaire 状态压缩 dp
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9462816.html
Copyright © 2011-2022 走看看