zoukankan      html  css  js  c++  java
  • 联赛练习:draw

    【题目描述】

    有一天, WJK不小心透露出了他会算命的秘密,大家纷纷前往拜访,于是WJK拿出私藏的小木箱,给大家露两手。(结果是要收钱的!)

    小木箱里装有N张牌,每张牌分别有一个价格vi和人品值ri,现在要求从中选出K张牌,使得单位人品值最大。(单位人品值=总人品值之和/总价格之和)

    【输入】

    第1行:两个整数N和K(1<=K<=N<=10^5) .

    第二至N+1行为每张牌的价格vi和人品值ri。(1<=vi,ri<=10^7)

    【输出】

    第1行:单位人品的最大值(精确到小数点后两位).

    【输入样例】

    3 2
    2 2
    5 3
    2 1
    

    【输出样例】

    0.75

    【提示】

    选1号和3号牌,单位人品值为(2+1)/(2+2)=0.75

     题解:

    01分数规划

    设:

    $$sum_{i=1}^n frac{r_ix_i}{v_ix_i}>=p$$

    其中x为1或0,即选或不选

    现在考虑最大化p,显然,p具有单调性,所以可以二分p

    那么如何验证呢?

    整理上式,有

    $$sum_{i=1}^nr_ix_i=sum_{i=1}^npv_ix_i$$

    移项,得:

    $$sum_{i=1}^nx_i(r_i-pv_i)>=0$$

    因此,对于p,我们可以先算出每一个r-k*p,接着,取前k大的值求和(相当于前k大的x取1,其余取0),若其和>=0,则证明此时的p合法

    另外二分小数这东西略蛋疼......实际上你只需要限制它的二分次数为55次即可

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    int n,k;
    int v[100005],r[100005];
    double ans;
    bool cmp(double a,double b)
    {
        return a>b;
    }
    bool check(double p)
    {
        double sum=0.00;
        double rt[100005];
        for(int i=1;i<=n;i++)
            rt[i]=(double)r[i]-p*(double)v[i];
        sort(rt+1,rt+1+n,cmp);
        for(int i=1;i<=k;i++)
            sum+=rt[i];
        if(sum>=0.00)
           return true;
        else
           return false;          
    }
    int main()
    {
        double t=-1.00;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&v[i],&r[i]);
                t=(double)r[i]/v[i]>t?(double)r[i]/v[i]:t;
            }
        int tot=0;        
        double L=0.01,R=t;
        while(tot<=55)
              {
                     tot++;
                     double mid=(L+R)/2;
                     if(check(mid))
                        {
                              ans=mid;
                              L=mid+0.01;
                        }
                     else
                       R=mid-0.01;   
              }
        printf("%.2lf",ans);                          
        return 0;
    }
    View Code
  • 相关阅读:
    【Leetcode】【Easy】Remove Duplicates from Sorted List
    【Leetcode】【Easy】Pascal's Triangle II
    【Leetcode】【Easy】Pascal's Triangle
    【Leetcode】【Easy】Binary Tree Level Order Traversal II
    【Leetcode】【Easy】Binary Tree Level Order Traversal
    【Leetcode】【Easy】Maximum Depth of Binary Tree
    【Leetcode】【Easy】Minimum Depth of Binary Tree
    【Leetcode】【Easy】Balanced Binary Tree
    【Leetcode】【Easy】Symmetric Tree
    如何使用Action.Invoke()触发一个Storyboard
  • 原文地址:https://www.cnblogs.com/nanjolno/p/9302485.html
Copyright © 2011-2022 走看看