ZOJ 3822 Domination 概率dp 难度:0
Edward is the headmaster of Marjar University. He is enthusiastic about chess and often plays chess with his friends. What's more, he bought a large decorative chessboard with N rows and M columns.
Every day after work, Edward will place a chess piece on a random empty cell. A few days later, he found the chessboard was dominated by the chess pieces. That means there is at least one chess piece in every row. Also, there is at least one chess piece in every column.
"That's interesting!" Edward said. He wants to know the expectation number of days to make an empty chessboard of N × M dominated. Please write a program to help him.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
There are only two integers N and M (1 <= N, M <= 50).
Output
For each test case, output the expectation number of days.
Any solution with a relative or absolute error of at most 10-8 will be accepted.
Sample Input
2 1 3 2 2
Sample Output
3.000000000000 2.666666666667
概率dp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #include<cstdio> #include<cstring> using namespace std; double dp[60][60][3000]; void printdp( int x, int y){ for ( int i=0;i<=x;i++){ for ( int j=0;j<=y;j++){ for ( int k=0;k<=i*j;k++){ printf ( "dp[%d][%d][%d]%f " ,i,j,k,dp[i][j][k]); } } puts ( "" ); } } int main(){ int T; int n,m; scanf ( "%d" ,&T); while (T--){ scanf ( "%d%d" ,&n,&m); for ( int i=0;i<=n;i++){ for ( int j=0;j<=m;j++){ memset (dp[i][j],0, sizeof (dp[i][j])); } } dp[0][0][0]=1; for ( int i=0;i<=n;i++){ for ( int j=0;j<=m;j++){ for ( int k=0;k<=i*j;k++){ if (k==n*m||(i==n&&j==m)) continue ; if (k<i*j)dp[i][j][k+1]+=dp[i][j][k]*(i*j-k)/(n*m-k); if (i<n)dp[i+1][j][k+1]+=dp[i][j][k]*(n-i)*j/(n*m-k); if (j<m)dp[i][j+1][k+1]+=dp[i][j][k]*(m-j)*i/(n*m-k); if (i<n&&j<m)dp[i+1][j+1][k+1]+=dp[i][j][k]*(n-i)*(m-j)/(n*m-k); } } } double sum=0; for ( int k=0;k<=n*m;k++){ sum+=k*dp[n][m][k]; // sum+=dp[n][m][k]; // printf("dp[%d]%f\n",k,dp[n][m][k]); } //printdp(n,m); //double ans=(double)sub/(double)sum; printf ( "%.12f\n" ,sum); } return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 不到万不得已,千万不要去外包
· C# WebAPI 插件热插拔(持续更新中)
· 会议真的有必要吗?我们产品开发9年了,但从来没开过会
· 【译】我们最喜欢的2024年的 Visual Studio 新功能
· 如何打造一个高并发系统?