[正睿Oj255] 世界杯 解题报告 (期望)

YJC最近在研究世界杯,他拿一半财产压了德国队,另一半财产压了阿根廷队,结果可想而知。YJC表示非常angry,于是又开始研究博彩公司的盈利原理。

假设在世界杯决赛前,有n个人参与了赌博。第i个人认为法国队赢的概率是p[i],克罗地亚队赢的概率是1p[i]

对于每一只球队,如果根据博彩公司给出的赔率第i个人的期望收益非负,则他会给这只球队下注a[i]

(设赔率为x,某人下注了y元,如果他赢了可以返还xy元,他输了则会返还0元。不论输赢,下注的钱均不返还)。

如果两只球队期望收益均非负,则他会给两只球队各下注a[i]元。

现在博彩公司要决定法国队和克罗地亚队的赔率,使得在自身收益最小的胜负情况下的收益最大。

输入格式

第一行输入一个数n,表示总人数。

接下来n行,每行两个实数a[i]p[i],均保留不超6位小数。

输出格式

一个实数,表示无论比赛结果如何,博彩公司最小收益的最大值,保留6位小数。

样例1

样例输入

3
1 0.1
2.233 0.1
3.666 0.1

样例输出

0.000000

样例2

见下载文件

限制

对于10%的数据,保证n80

对于30%的数据,保证n400

对于50%的数据,保证n5000

对于80%的数据,保证n100000

对于100%的数据,保证n10000000a[i]1000p[i]1

时间限制:2s

内存限制:512MB

若法国队赔率为x,下注y

期望收益:x * y * p[i] + 0 * (1 - p[i]) - y = y * (x * p[i] -1)

y>0,则若x * p[i] >= 1就会下注

移项得图片中的结论 ,克罗地亚同理

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

const int N=1e6+15;
int n;
int id[N];
double ans;
double a[N],p[N],sum[N];
bool cmp(int a,int b) {return p[a]>p[b];}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i],&p[i]),id[i]=i;
    sort(id+1,id+1+n,cmp);
    for (int i=1;i<=n;i++) sum[id[i]]=sum[id[i-1]]+a[id[i]];
    int l=1,r=n;
    while (l<=n&&r>=1)
    {
        double x1=1.0/p[id[l]],x2=1.0/(1-p[id[r]]);
        double s1=sum[id[l]],s2=sum[id[n]]-sum[id[r-1]];
        ans=max(ans,min(s1+s2-s1*x1,s1+s2-s2*x2));
        if (s1*x1>s2*x2) r--;
        else l++;
    }
    printf("%lf",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xxzh/p/9439118.html