题目:http://poj.org/problem?id=1322
题意:有C种不同颜色的巧克力,每种巧克力同样多,把巧克力一个一个拿到桌子上,当发现有相同颜色就把相同颜色的吃掉,求取出n个后,还剩m个在桌子上的概率。
刚开始被题目的数据范围吓住了,知道用dp,但不敢下手,看了discuss,尼玛把大于1000的奇数改为1001,偶数改为1000就行了,不知道为什么是对的,试着敲了下,居然过了~~~
很显然,当某时刻桌子上还剩m个巧克力,它们的颜色一定都不相同。用dp[i][j]表示取i个巧克力后,还剩j个的概率。则对每个dp[i][j],如果新拿出的巧克力与目前桌子上的巧克力颜色都不相同,则概率为(c-j+1)/c,若新拿出的巧克力与目前桌子上的某个巧克力颜色相同,则概率为(j+1)/c(原来桌上有j+1个,拿出来一个,吃了两个,最后剩下j个),于是dp[i][j]=dp[i-1][j-1]*(c-j+1)/c+dp[i-1][j+1]*(j+1)/c。
#include<cstdio>
#include<cstring>
double dp[1005][1005];
int main()
{
int c,n,m,i,j;
while(scanf("%d",&c),c)
{
scanf("%d%d",&n,&m);
if(m>c||m>n||(n+m)%2==1)
{
printf("0.000\n");
continue;
}
if(n>1000)
n=1000+n%2;
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(i=1;i<=n;i++)
for(j=0;j<=c;j++)
{
if(j==0)
dp[i][j]=dp[i-1][j+1]/c;
else if(j==c)
dp[i][j]=dp[i-1][j-1]/c;
else
dp[i][j]=dp[i-1][j-1]*(c-j+1)/c+dp[i-1][j+1]*(j+1)/c;
}
printf("%.3lf\n",dp[n][m]);
}
return 0;
}