zoukankan      html  css  js  c++  java
  • 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
    ",k,ans);
    49     }
    50     return 0;
    51 }
  • 相关阅读:
    Flash 全局安全性设置面板
    响应式布局的一个例子mark
    移动平台WEB前端开发技巧汇总
    自定义事件机制——观察者模式
    学习之响应式Web设计:Media Queries和Viewports
    常用栅格布局方案
    观察者模式的一个例子
    二进制文件转换为文本工具
    C#面向对象名词比较(二)
    MSN消息提示类
  • 原文地址:https://www.cnblogs.com/mj-liylho/p/6422283.html
Copyright © 2011-2022 走看看