[NOIP模拟赛]保证的利润

题目描述
运气是投注的基础。有些人通过深入了解他们所投注的知识来提高机会和收益。 我们将采取不同的方法。
各种博彩公司为同样的结果提供不同的赔率或配额。(赔率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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值