比赛-ZR DAY4 (07 Aug, 2018)

A. 世界杯

假设法国队的赔率是 \(x\) ,则第 \(i\) 个人下注法国队的充要条件是

\[(x-1)\cdot a_{i}\cdot p_{i}-a_{i}\cdot (1-p_i)\geq 0 \]

化简一下就是

\[x\geq\frac{1}{p_i} \]

类似的可以得出下注克罗地亚队的充要条件(假设赔率是 \(y\)

\[y\geq \frac{1}{1-p_i} \]

\(p_i\) 从大到小排序,显然下注法国队的是前缀 \([1, l]\) ,下注克罗地亚队的是一个后缀 \([r, n]\) 。彩票公司的利益是

\[\sum a[1...l]+\sum a[r...n]-max\left(\sum a[1...l]\cdot x, \sum a[r...n]\cdot y\right) \]

然后可以贪个心,当 \(max\) 内取前一项时考虑把 \(r\) 减去 \(1\) ,取后一项时考虑把 \(l\) 加上 \(1\) 。这样很可能不会改变 \(max\) 的取值,而使前面的式子的取值变大,它就很好。就是这样。

#include <cstdio> 
#include <algorithm>

using namespace std;

const int _N = 1020000;

struct data {
	double a, p;
	bool operator < (const data &tmp) const
	{
		return p > tmp.p;
	}
} A[_N];

int main()
{
//	freopen("ex_a2.in", "r", stdin);
	int N;
	double ans = 0;
	scanf("%d", &N);
	for (int i = 1; i <= N; ++i) scanf("%lf%lf", &A[i].a, &A[i].p);
	sort(A+1, A+1+N);
	int l = 1, r = N;
	double suml = A[1].a, sumr = A[N].a;
	while (l <= N && r >= 1) {
		double x = 1/A[l].p, y = 1/(1-A[r].p);
		ans = max(ans, suml+sumr-max(suml*x, sumr*y));
		if (suml*x > sumr*y) sumr += A[--r].a;
		else suml += A[++l].a;
	}
	printf("%.6lf\n", ans);
	return 0;
}

B. 数组

C. 淘汰赛

posted @ 2018-08-07 20:10  derchg  阅读(116)  评论(0编辑  收藏  举报