http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5376
很变态的题,单本人觉得此题写的太好了
一下是我的代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int sizen=55;
double dp[sizen*sizen][sizen][sizen];
int T;
int main()
{
int n,m;
int i,j,k;
scanf("%d",&T);
while(T--)
{
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;
scanf("%d%d",&n,&m);
for(k=1;k<=n*m-min(n,m)+1;k++)
for(i=1;i<=k&&i<=n;i++)
for(j=1;j<=k&&j<=m;j++)
if(i==n&&j==m)
dp[k][i][j]=dp[k-1][i-1][j]*(double)(j*(n-i+1))/(double)(n*m-k+1)+
dp[k-1][i][j-1]*(double)(i*(m-j+1))/(double)(n*m-k+1)+
dp[k-1][i-1][j-1]*(double)(n-i+1)*(double)(m-j+1)/(double)(n*m-k+1);
else
dp[k][i][j]=dp[k-1][i-1][j]*(double)(j*(n-i+1))/(double)(n*m-k+1)+
dp[k-1][i][j-1]*(double)(i*(m-j+1))/(double)(n*m-k+1)+
dp[k-1][i-1][j-1]*(double)(n-i+1)*(double)(m-j+1)/(double)(n*m-k+1)+
dp[k-1][i][j]*(double)(i*j-k+1)/(double)(n*m-k+1);
double ans=0;
for(k=1;k<=n*m-min(n,m)+1;k++)
ans+=(dp[k][n][m])*k;
printf("%.12lf\n",ans);
}
return 0;
}