有c种颜色的糖果,你每次可以取一个糖果放在桌子上,但是一旦桌子上已经有这个颜色的糖果了,那这两颗糖果都会没掉,问让你取n次糖果最后桌子上剩下m个糖果的概率是多少。
每种糖果要么是奇数,要么没有
定义 f [ i ] [ j ] f[i][j] f[i][j]为 i i i次后剩下 j j j个糖果的概率
f [ i ] [ j ] = f [ i − 1 ] [ j − 1 ] ∗ c − j + 1 c + f [ i − 1 ] [ j + 1 ] ∗ j + 1 c f[i][j]=f[i-1][j-1]*\frac{c-j+1}{c}+f[i-1][j+1]*\frac{j+1}{c} f[i][j]=f[i−1][j−1]∗cc−j+1+f[i−1][j+1]∗cj+1
但是这样太慢了…那么可以写矩阵乘法…但是太懒了
n n n可以缩小,因为当 n n n很大时概率趋于稳定
但是 ! ! !压缩 n n n后需要保证奇偶性,因为转移是与奇偶性有关的.
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
int n,m;
double c;
double f[1009][109];
int main()
{
while( cin >> c && c>0.0000001 )
{
cin >> n >> m;
if( m>c )
{
printf("0.000\n");
continue;
}
f[0][0] = 1.0;
if( n>=1000 ) n=1000+(n%2);
for(int i=1;i<=n;i++)
{
int limit = min( i,(int)c );
for(int j=0;j<=limit;j++)
{
double p1 = (c-j+1)/c, p2 = (j+1)/c;
if( j>=1 ) f[i][j] += p1*f[i-1][j-1];
f[i][j] += f[i-1][j+1]*p2;
}
}
printf("%.3f\n",f[n][m] );
memset( f,0,sizeof f);
}
}