题目描述
运气是投注的基础。有些人通过深入了解他们所投注的知识来提高机会和收益。 我们将采取不同的方法。
各种博彩公司为同样的结果提供不同的赔率或配额。(赔率x意味着如果你投注1欧元并正确预测结果,那么你会收到x欧元。 如果你不正确地预测结果,你当然什么都得不到。 请注意,不管结果如何,你都将支付1欧元。)是否可以通过巧妙地放置几个赌注来确定赚取利润呢? 你想要使这个保证的利润尽可能的大。
我们想打赌的事件有两个可能的结果。 有n个博彩公司提供不同的赔率。第i个博彩公司为第一个结果提供的赔率为ai,为第二个结果提供的赔率为bi。
在任何一个博彩公司你都可以选择下注或者是不下注。 你甚至可以在同一个博彩公司同时下注这两个结果。 记住,所有的赌注必须是1欧元。但是你不能与同一个博彩公司多次下注相同的结果。
当第一个结果出现了,如果你在第i个博彩公司正好下注第一个结果,你就能从该公司获得ai欧元。同理,当第二个结果出现了,如果你在第i个博彩公司正好下注第二个结果,你就能从该公司获得bi欧元。当然,每一次下注都将花费1欧元。
如果你采用最佳的下注策略,那么无论结果如何,你能得到的最大的保证利润是多少呢?
输入格式
第1行:1个整数n(1≤n≤100000),表示博彩公司的数量
接下来n行,每行2个浮点数ai和bi(1.0≤ai,bi≤1000.0),表示第i个博彩公司对两个结果的赔率。每个浮点数最多4位十进制数。
输出格式
第1行:1个浮点数,表示能够取得的最大保证利润。保留4位小数。
输入样例
4
1.4 3.7
1.2 2
1.6 1.4
1.9 1.5
输出样例
0.5000
样例说明
最佳下注策略是在第一个博彩公司投注第二个结果,在第三和第四家博彩公司下注第一个结果。 这样,当出现第一个结果,我们将获得1.6 + 1.9-3 = 0.5。如果是第二个结果,我们将获得3.7-3 = 0.7。所以我们保证有0.5欧元的利润。
题解
设下注i家公司a结果,赔率和为A;下注j家公司b结果,赔率和为B;
要求利润最大,那一定要下注尽量少的公司使得赔率尽量大,于是将a和b从大到小排序。
选择时一定要保持A与B的值接近,因为利润为max( min( A, B )-i-j ),若本来A<B,又去下注b结果使B增大,那么当b结果未出现时,利润会因A要多减而变小。
#include<cstdio> #include<algorithm> using namespace std; const int N=200005; int n; double w, A, B, a[N], b[N]; bool cmp( double a, double b ) { return a>b; } int main() { scanf( "%d", &n ); for( int i=1; i<=n; i++ ) scanf( "%lf%lf", &a[i], &b[i] ); sort( a+1, a+n+1, cmp ); sort( b+1, b+n+1, cmp ); for( int i=0, j=0; i<n || j<n; ) { if( A<B && i<n ) A+=a[++i]; else if( j<n ) B+=b[++j]; else break; w=max( w, min( A, B )-i-j ); } printf( "%.4f\n", w ); return 0; }
[NOIP模拟赛]保证的利润
最新推荐文章于 2024-11-24 21:59:43 发布