您的位置:首页 > 其它

zoj 3822 概率dp

2014-11-28 21:34 357 查看
/*
题目大意:一个n*m的棋盘,每天放一个棋子,每行每列至少有一个棋子时结束。求达到每行每列至少有一个棋子的天数的数学期望。
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn=55;
double dp[maxn*maxn][maxn][maxn];//放i颗棋子,j行有棋子,k列有棋子

int main()
{
int t,n,m,i,j,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;
int top=n*m;
for(i=1;i<=top;i++)
{
for(j=1;j<=i && j<=n;j++)
{
for(k=1;k<=i && k<=m;k++)
{
dp[i][j][k]=dp[i-1][j][k-1]*((m-k+1)*j)/(n*m-i+1)+//原有行,新的列中
dp[i-1][j-1][k]*((n-j+1)*k)/(n*m-i+1)+//原有列,新的行中
dp[i-1][j-1][k-1]*((n-j+1)*(m-k+1))/(n*m-i+1);//新的行,新的列中
if(!(n==j && m==k))//没到终点可以放在原有行,原有列中
dp[i][j][k]+=dp[i-1][j][k]*(j*k-i+1)/(n*m-i+1);
}
}
}
double ans=0;
for(i=1;i<=top;i++)
ans+=dp[i]
[m]*i;
printf("%.10lf\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: