【Gym-101194E】Problem E. Bet - The 2016 ACM-ICPC Asia China-Final Contest

Bet 題目鏈接

pdf鏈接

題目描述

Input file: Standard Input
Output file: Standard Ouptut
Time limit: 1 second


The Codejamon game is on fire! Fans across the world are predicting and betting on which team will win the game.A gambling company is providing betting odds for all teams; the odds for the i-th team is Ai:Bi.
For each team, you can bet any positive amount of money, and you do not have to bet the same amount on each team. If the i-th team wins, you get your bet on that team back, plus BiAi\frac{Bi}{Ai} times your bet on that team.
For example, suppose that there are two teams, with odds of 5:35:3 and 2:72:7 and you bet $ 20 on the first team and $ 10 on the second team. If the first team wins, you will lose your $ 10 bet on the second team, but you will receive your $ 20 bet back, plus 35×20=12\frac{3}{5} × 20 = 12, so you will have a total of $ 32 at the end. If the second team wins, you will lose your $ 20 bet on the first team, but you will receive your $ 10 bet back, plus 72×10=35\frac{7}{2} × 10 = 35, so you will have a total of $ 45 at the end. Either
way, you will have more money than you bet ($ 20+$ 10 = $ 30).
As a greedy fan, you want to bet on as many teams as possible to make sure that as long as one of them wins, you will always end up with more money than you bet. Can you figure out how many teams you can bet on?

Input

The input starts with one line containing exactly one integer T, which is the number of test cases.


Each test case starts with one line containing an integer N: the number of teams in the game. Then, N more lines follow. Each line is a pair of numbers in the form Ai:Bi (that is, a number Ai, followed by a colon, then a number Bi, with no spaces in between), indicating the odds for the i-th team.

Output

For each test case, output one line containing “Case #x: y”, where x is the test case number(starting from 1) and y is the maximum number of teams that you can bet on, under the conditions specified in the problem statement.


Limits
• 1 ≤ T ≤ 100.
• 1 ≤ N ≤ 100.
• 0 < Ai, Bi < 100.
• Both Ai and Bi have at most 3 digits after the decimal point.

Sample Input

1
3
1:1.1
1:0.2
1.5:1.7

Sample Output

Case #1: 2

Note

In sample case #1, one optimal strategy is to bet 1.5 dollars on the first team and 1.5 dollars on the third team. If the first team wins, you will get 1.5 + 1.5 × (1.1/1) = 3.15 dollars back, and if the third team wins, you will get 1.5 + (1.7/1.5) × 1.5 = 3.2 dollars back. Both of these are higher than the total money that you bet (1.5 + 1.5 = 3 dollars). However, there is no way to bet on all three teams and be guaranteed a profit.

題意

有一個賭徒,要去賭錢。
賭錢規則如下:
  1. 有 N 個隊的比賽。
  2. 每個隊都有一個屬性 Ai:Bi。
  3. 你可以下注任意多個隊贏。
  4. 如果你下注的隊贏了,你就可以拿回你下注的錢,並加上 你下注的錢 * (Bi/Ai)。(如果你給第 i 支隊伍下注 X 元,並且這支隊伍贏了,你可以獲得 X + X * (Bi/Ai) 元)。
  5. 沒有贏的隊伍的下注的錢,全部沒收。
題目給 N 個隊伍,問你最多可以選多少支隊伍出來,至少存在一種方法,使得不管這些隊伍裏哪支隊伍贏了,你都有錢賺。
例如題目舉的栗子,第一支隊伍賠率爲 5:3,第二支隊伍爲 7:2,你只要給第一支隊伍投 20 元,給第二支隊伍投 10 元,不管這兩支隊伍中哪一個贏了,你都有錢賺。

題解

我們假設有 nn 支隊伍,總存在至少一種下注方法,使得不管結果如何,都可以賺錢。
我們不妨把 BA\frac{B}{A} 叫做賠率。

n=1n = 1 時,不管怎麼投注,11 支隊伍必勝。
n=2n = 2 時,

隊伍 賠率 下注金額
1 a x
2 b y

如果第一隊贏,若要賺錢,則有式子:x+ax&gt;x+yx + ax &gt; x + y (獲得的錢要大於投注的錢)
如果第二隊贏,若要賺錢,則有式子:y+by&gt;x+yy + by &gt; x + y
如果要讓不管哪一隊贏都可以賺錢,顯然要讓兩式聯立有解:{x+ax&gt;x+yy+by&gt;x+y\begin{cases} x + ax &gt; x + y\\ y + by &gt; x + y\\ \end{cases}
我們可以對這個式子做一下變換,{x(1+a)&gt;x+yy(1+b)&gt;x+y\begin{cases} x(1 + a) &gt; x + y\\ y(1 + b) &gt; x + y\\ \end{cases} 然後變成:{1+a&gt;x+yx1+b&gt;x+yy\begin{cases} 1 + a &gt; \frac{x + y}{x}\\ 1 + b &gt; \frac{x + y}{y}\\ \end{cases}
根據題目,可知賠率 aabb 都是大於 00 的,所以式子的左邊和右邊都是大於 00 的。
因此我們可以取一下倒數,變成:{11+a&lt;xx+y11+b&lt;yx+y\begin{cases} \frac{1}{1 + a} &lt; \frac{x}{x + y}\\ \frac{1}{1 + b} &lt; \frac{y}{x + y}\\ \end{cases}
至此, n=2n = 2 的結果已經很明顯了,兩式右邊相加爲 11,即 xx+y+yx+y=1\frac{x}{x + y} + \frac{y}{x + y} = 1
由於 xxyy 是下注金額,是可以任意取值的,所以兩式等號右邊可以任意取成相加爲 11 的實數。
因此只要兩式的左邊 11+a\frac{1}{1 + a}11+b\frac{1}{1 + b} 只要相加小於 11,右邊的 xx+y\frac{x}{x + y}yx+y=1\frac{y}{x + y} = 1 就必然存在至少一個解 (x,y)(x, y) 使得 {11+a&lt;xx+y11+b&lt;yx+y\begin{cases} \frac{1}{1 + a} &lt; \frac{x}{x + y}\\ \frac{1}{1 + b} &lt; \frac{y}{x + y}\\ \end{cases} 成立。


我們可以繼續觀察 n=3n = 3 的情況。

隊伍 賠率 下注金額
1 a x
2 b y
3 c z

此時根據 n=2n = 2 一樣的推導操作,可以得到: {11+a&lt;xx+y+z11+b&lt;yx+y+z11+c&lt;zx+y+z\begin{cases} \frac{1}{1 + a} &lt; \frac{x}{x + y + z}\\ \frac{1}{1 + b} &lt; \frac{y}{x + y + z}\\ \frac{1}{1 + c} &lt; \frac{z}{x + y + z}\\ \end{cases}
因此,只要 11+a\frac{1}{1 + a}11+b\frac{1}{1 + b}11+c\frac{1}{1 + c} 的和小於 11, 就必然至少存在一個解 (x,y,z)(x, y, z) 使得上面式子成立。


因此當 nn 爲任意實數時,我們設賠率爲 pip_i,投注爲 tit_i
可得:
{11+p1&lt;t1t1+t2++tn11+p2&lt;t2t1+t2++tn11+pn&lt;tnt1+t2++tn\begin{cases} \frac{1}{1 + p_1} &lt; \frac{t_1}{t_1 + t_2 +\cdots + t_n}\\ \frac{1}{1 + p_2} &lt; \frac{t_2}{t_1 + t_2 +\cdots + t_n}\\ \quad\quad\quad\vdots\\ \frac{1}{1 + p_n} &lt; \frac{t_n}{t_1 + t_2 +\cdots + t_n}\\ \end{cases}
只要式子左邊加起來小於 11, 則一定存在至少一個解 (t1,t2,&ThinSpace;,tn)(t_1,t_2,\cdots,t_n) 使得等式成立。


因此,對於這道題,我們只需要找到 11+(B/A)\frac{1}{1 + (B/A)} 加起來小於 11 的最大個數就行了。
我們可以考慮用貪心的方法,先把 11+(B/A)\frac{1}{1 + (B/A)} 從小到大排序,直到和大於 11

但是對於這道題而言,double 的精度不符合要求,需要用到 long double

並且輸入數據之間有 ":",用 printf 會出現未知錯誤,windows 上無法體現,judge 機器會返回 WA。

代碼

#include<algorithm>
#include<iostream>
using namespace std;
long double a[1000], x, y;

int main(){
	int T, n, ca = 0;
	char c;
	cin >> T;
	while (T--) {
		cin >> n;
		for (int i = 0; i < n; i++) {
			cin >> x >> c >> y;
			a[i] = 1.0/(long double)(y/x + 1);
		}
		sort(a, a + n);
		long double sum = 0;
		int i;
		for (i = 0; i < n; i++) {
			sum += a[i];
			if (sum >= 1) {
				break;
			}
		}
		printf("Case #%d: %d\n", ++ca, i);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章