Gym 101194E / UVALive 7901 - Ice Cream Tower - [数学+long double][2016 EC-Final Problem E]

题目连接:php

http://codeforces.com/gym/101194/attachmentsc++

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5923spa

 

题意:code

现有 $N$ 支队伍参加比赛,只有一个队伍能获胜。给出每一个队伍一个赔率 $A_i:B_i$,你往这个队投 $x$ 元,若该队获胜你可获得 $\frac{A_i+B_i}{A_i}\cdot x$ 元,不然获得 $0$ 元。blog

首先你要确保投注的每一个队伍中,无论哪一个胜利了你均可以赚,如今要求最多能够投多少个队伍。ci

 

题解:get

假设你总共投注 $x(x>0)$ 元,且对于第 $i$ 个队伍你投了 $p_i \cdot x(0 \le p_i \le 1)$ 元。那么,必须知足 $p_i \cdot x \cdot \frac{A_i+B_i}{A_i}>x \Rightarrow p_i > \frac{A_i}{A_i+B_i}$it

显然,$\sum p_i = 1$,必须知足 $\sum \frac{A_i}{A_i+B_i} < 1$,同时无论你选择多少队伍选择哪几个队伍,io

又,只要知足 $\sum \frac{A_i}{A_i+B_i} < 1$ 我必然能够调整每一个队伍相应的 $p_i$ 使得 $p_i > \frac{A_i}{A_i+B_i}$。class

所以,只要尽量选择 $\frac{A_i}{A_i+B_i}$ 小的队伍,直到 $\sum \frac{A_i}{A_i+B_i} \ge 1$ 为止。

double的精度不够,须要用long double。

 

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
int n;
long double c[maxn];
int main()
{
    int T;
    cin>>T;
    for(int kase=1;kase<=T;kase++)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            double a,b;
            scanf("%lf:%lf",&a,&b);
            a=floor(a*1000);
            b=floor(b*1000);
            c[i]=a/(a+b);
        }
        sort(c,c+n);
        int ans=0;
        long double sum=0;
        for(int i=0;i<n;i++)
        {
            sum+=c[i];
            if(sum>=1) break;
            ans++;
        }
        printf("Case #%d: %d\n",kase,ans);
    }
}
相关文章
相关标签/搜索