思路:dp
(1):dp[N][M]表示取N个后剩下M个的概率;
(2):利用N很大时的收敛性:
if(N>1000)
N=1000+N%2;
状态转移方程:
dp[N+1][M+1]=dp[N][M]*(C-M)/C; if(M+1<=C)
dp[N+1][M-1]=dp[N][M]*M/C; if(M-1>=0)
dp[N][M]=0; if((N+M)%2!=0)
CODE:
/*DP+概率*/
/*AC代码:94ms*/
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
using namespace std;
double dp[1005][105];
int C,N,M;
int main()
{
int i,j;
while(scanf("%d",&C),C)
{
scanf("%d%d",&N,&M);
memset(dp,0,sizeof(dp));
dp[0][0]=dp[1][1]=1;
if(M>C||M>N||(M+N)%2!=0)
{printf("0.000\n");continue;}
if(N>1000)//收敛
N=1000+N%2;
for(i=1;i<=N;i++)
{
j=i%2;
while(j<=C&&j<=i)
{
if(j+1<=C)
dp[i+1][j+1]+=dp[i][j]*(C-j)*1.0/C;
if(j-1>=0)
dp[i+1][j-1]+=dp[i][j]*j*1.0/C;
j+=2;
}
}
printf("%.3lf\n",dp[N][M]);
}
return 0;
}