Kickstart Practice Round 2017 Google


Problem B. Vote

A and B are the only two candidates competing in a certain election. We know from polls that exactly N voters support A, and exactly M voters support B. We also know that N is greater than M, so A will win.

Voters will show up at the polling place one at a time, in an order chosen uniformly at random from all possible (N + M)! orders. After each voter casts their vote, the polling place worker will update the results and note which candidate (if any) is winning so far. (If the votes are tied, neither candidate is considered to be winning.)

What is the probability that A stays in the lead the entire time -- that is, that A will always be winning after every vote?

Input

The input starts with one line containing one integer T, which is the number of test cases. Each test case consists of one line with two integers N and M: the numbers of voters supporting A and B, respectively.

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 probability that A will always be winning after every vote.

y will be considered correct if y is within an absolute or relative error of 10-6 of the correct answer. See the FAQ for an explanation of what that means, and what formats of real numbers we accept.

Limits

1 ≤ T ≤ 100.

Small dataset

0 ≤ M < N ≤ 10.

Large dataset

0 ≤ M < N ≤ 2000.

Sample

Input 
2
2  1
1 0
Output 
Case #1: 0.33333333
Case #2: 1.00000000

In sample case #1, there are 3 voters. Two of them support A -- we will call them A1 and A2 -- and one of them supports B. They can come to vote in six possible orders: A1 A2 B, A2 A1 B, A1 B A2, A2 B A1, B A1 A2, B A2 A1. Only the first two of those orders guarantee that Candidate A is winning after every vote. (For example, if the order is A1 B A2, then Candidate A is winning after the first vote but tied after the second vote.) So the answer is 2/6 = 0.333333...

In sample case #2, there is only 1 voter, and that voter supports A. There is only one possible order of arrival, and A will be winning after the one and only vote.

思路:

dp[i][j]:i個A與j個B的未結束(票數領先)的情況數,則dp[i][j]=dp[i-1][j]+dp[i][j-1] 表示由i-1個A,j個B或者i個A,j-1個B轉化而來。dp[0][0]=1表示開始時未結束。

之后得到dp[n][m]為n個A,m個B的情況數,之后乘上n!*m!為總的排列數。

難點:

1.large dataset里n最大為2000,最后的排列數和dp可能大於2000!(3*10^5735),所以需要用對數運算。

2.乘除轉化為對數加減,加法可轉化為:c=log(e^a+e^b)->c=log(e^a(1+e^(b-a)))=a+log(1+e^(b-a))  這樣就不會溢出了  :)

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<queue>
 6 #define pi acos(-1.0)
 7 #define mj
 8 #define inf 0x3f3f3f
 9 #define  db double
10 typedef  long long  ll;
11 using namespace std;
12 const int N=1e5+5;
13 db  dp[2002][2002];
14 void init()
15 {
16     for(int i=0;i<2002;i++){
17         for(int j=0;j<2002;j++)
18             dp[i][j]=-1;
19     }
20     dp[0][0]=log(1.0);
21     for(int i=0;i<2002;i++){
22         for(int j=0;j<2002;j++){
23             if(i>j){
24                     if(dp[i-1][j]!=-1&&dp[i][j-1]!=-1) dp[i][j]=dp[i-1][j]+log(1+exp(dp[i][j-1]-dp[i-1][j]));
25                     else if(dp[i-1][j]==-1&&dp[i][j-1]!=-1) dp[i][j]=dp[i][j-1];
26                     else if(dp[i-1][j]!=-1&&dp[i][j-1]==-1) dp[i][j]=dp[i-1][j];
27                 }
28         }
29     }
30 }
31 int main()
32 {
33     #ifdef mj
34     freopen("data.in","r",stdin);
35     freopen("data.out","w",stdout);
36     #endif // mj
37     int t,n,m;
38     scanf("%d",&t);
39     init();
40     for(int k=1;k<=t;k++){
41         scanf("%d%d",&n,&m);
42         db ans=0;
43         for(int i=1;i<=m;i++){
44             ans+=(db)log(i)-(db)log(n+i);
45         }
46         ans+=(db)dp[n][m];
47         ans=exp(ans);
48         printf("Case #%d: %.8f\n",k,ans);
49     }
50     return 0;
51 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM