Gym 101194E / UVALive 7901 - Ice Cream Tower - [数学+long double][2016 EC-Final Problem E]
题目链接:
http://codeforces.com/gym/101194/attachments
题意:
现有 $N$ 支队伍参加比赛,只有一个队伍能获胜。给出每个队伍一个赔率 $A_i:B_i$,你往这个队投 $x$ 元,若该队获胜你可得到 $\frac{A_i+B_i}{A_i}\cdot x$ 元,否则得到 $0$ 元。
首先你要确保投注的每个队伍中,不管哪个胜利了你都可以赚,现在要求最多可以投多少个队伍。
题解:
假设你总共投注 $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}$
显然,$\sum p_i = 1$,必须满足 $\sum \frac{A_i}{A_i+B_i} < 1$,同时不管你选择多少队伍选择哪几个队伍,
又,只要满足 $\sum \frac{A_i}{A_i+B_i} < 1$ 我必然可以调整每个队伍相应的 $p_i$ 使得 $p_i > \frac{A_i}{A_i+B_i}$。
因此,只要尽可能选择 $\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); } }
转载请注明出处:https://dilthey.cnblogs.com/