众所周知,每一枚硬币都有两面,假定投掷一枚硬币,得到正面和反面的概率是一样的。小Q有一天和好朋友在玩投掷硬币的游戏,他投了n枚硬币,已知至少有p正,q反,求n枚硬币正面向上的期望是多少。
分析:
1.根据样例,分数取模的公式为:
其中4是期望的分子,3是期望的分母
printf("%d\n",(4%1000000007+1000000007)/3);
原理:
https://www.cnblogs.com/dear_diary/p/10835168.html
下面是“分数”模运算的定义:
b, m互质
k = a/b (mod m) <=> kb = a (mod m)
这里求 x = 1/17 (mod 2668)
<=>17x = 1 (mod 2668)
<=>17x = 2668k + 1 (k∈整数)
取合适的k使得17|(2668k+1)
这里刚好17 | (2668 + 1)
所以k = 1, x = (2668+1)/17 = 157
当然,当k = 1 + 17n 时,
x = (2668 + 17·n·2668 + 1)/17 = 157 + 2668n
也符合条件(n任意整数)
但如果限定 2668 > x > 0,x是唯一的。
2.计算期望
(1)首先要计算多少情况,
比如:3 1 0时,由于硬币根据题意是不相同的,存在排列数。
正最少1个 | 负最少0个 | 种类数 |
---|---|---|
1 | 2 | C31=3 从3个里选出一个为正,剩下的是反 |
2 | 1 | C32=3 从3个里选出2个为正 |
3 | 0 | C33=1 从3个里选出3个为正 |
所以有1+3+3=7种,
计算期望:
(1/7*
1)*
C31+(1/7*
2) *
C32+(1/7*
3)*
C33=9/7
比如:2 1 0时,由于硬币根据题意是不相同的,存在排列数。
正最少1个 | 负最少0个 | 种类数 |
---|---|---|
1 | 1 | C21=2 从2个里选出一个为正,剩下的是反 |
2 | 0 | C22=1 从2个里选出2个为正 |
有3种
计算期望:
(1/3*
1)*
C21+1/3*
2 = 4/3
这样一来就很简单了,按照上面的思路写代码:
#include <stdio.h>
#include <stdlib.h>
/**
* 计算n!
**/
int CalcuNum(int num){
int i=1;
int calcu=1;
do
{
calcu*=i;
i++;
}
while(i<=num);
//printf("%d n!=%d\n",num,calcu);
return calcu;
}
/**
* 计算排列数Cin,i=up,n=num
*/
int CalcuCn(int up,int num){
return CalcuNum(num)/(CalcuNum(up)*CalcuNum(num-up));
}
int main()
{
int num=0;
int pos=0;
int neg=0;
scanf("%d %d %d",&num,&pos,&neg);
int i=pos;
int category=0;
int exceptup=0;
for(i=pos;i<=num-neg;i++){
//计算种类数
int cn=CalcuCn(i,num);
category+=cn;
printf("%d个正, %d个反,有%d种,累计%d种\n",i,num-i,cn,category);
//计算期望的分子
exceptup+=cn*i;
}
//期望=期望的分子/排列种类数目
printf("求模得到:\n");
printf("%d\n",(exceptup%1000000007+1000000007)/category);
return 0;
}