题目描述:
1639 绑鞋带
有n根鞋带混在一起,现在重复n次以下操作:随机抽出两个鞋带头,把它们绑在一起。可以想象,这n次之后將不再有单独的鞋带头,n条鞋带系成了一些环。那么有多大概率刚好所有这些鞋带只形成了一个环?
收起
输入
仅一行,包含一个整数n (2<=n<=1000)。
输出
输出一行,为刚好成环的概率。
输入样例
2
输出样例
0.666667
思路一:
step1:我们考虑,一根鞋带,p=1.0;
step2:然后考虑 两根鞋带,分别是AB,CD,不失一般性,我们先拿A然后有3种情况,
AB,AC,AD,其中AB是不可取的,因为已经成环了,舍弃,所有有2/3的概率(AC,AD)把这两
根鞋带系成一根,那么就成了step1的情况。p=2/3*1;同理,三根鞋带,有4/5的概率变成两
根鞋带的情况,p=4/5*2/3*1;规律就出来了。
思路二:
组合数学
n根鞋带要组成一个环,那么显然与连成一根鞋带之前不成环是充要条件;
假设当前还剩下 i (i>1) 根鞋带,要从中选择两根鞋带头连接后不成环的概率为
pi = 不成环的选择方法数 / 所有选择方法数
所有方法数 = C(2*i, 2) = 2 * i * (2*i - 1) / 2 = i * (2*i - 1)
成环的方法数 = C(i, 1) = i
不成环的方法数 = 所有方法数 - 成环方法数 = i * (2*i - 2)
所以 pi = 不成环的选择方法数 / 所有选择方法数 = (2*i - 2) / (2*i - 1)
由此得到了i > 1时的 pi;
对于每一个 i 的情况都可以看作是相互独立的事件,那么显然有
p = ∑pi = ∑(2*i - 2) / (2*i - 1) (2 =< i <= n);
思路一代码实现:
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=2e5+100;
LL gcd(LL x,LL y){
return y==0?x:gcd(y,x%y);
}
int main(){
LL n,a,b,fz,fm,d;
double ans=1;
while(cin>>n){
a=b=fz=fm=1;
for(int i=2;i<=n;i++){
a=(b+1);
b=(a+1);//分别计算分子分母会爆精度
ans*=1.0*a/b;
}
printf("%.6lf\n",ans);
}
return 0;
}
THE END;