• ZOJ 3822 Domination


    题意:
    有一个(n * m)的棋盘,有一个人每天随机再一个空位上放一个棋子,问空棋盘变成每一行每一列都至少有一枚棋子的棋盘的期望天数是多少?

    思路:
    (dp[i][j][k])表示(i)行至少有一枚棋子,(j)列至少有一枚棋子,已经放了(k)枚棋子的概率是多少.

    那么(dp[i][j][k])可从以下四种状态转移过来:

    1. (dp[i - 1][j][k - 1]),可能性为((n - i + 1) * j / (sum - k + 1))
    2. (dp[i][j - 1][k - 1]),可能性为((m - j + 1) * i / (sum - k + 1))
    3. (dp[i - 1][j - 1][k - 1]),可能性为((n - i + 1) * (m - j +1) / (sum - k + 1))
    4. (dp[i][j][k - 1]),可能性为((i * j - k + 1) / (sum - k + 1))
      注意第四种状态在(i == n && j == m)的时候不要再转移了,因为根据题意,这个状态为终止状态。
      上式中的(sum = n * m)



    #include <bits/stdc++.h>
    using namespace std;
    
    #define db double
    #define N 60
    db f[N][N][N * N];
    
    int main()
    {
    	int T; cin >> T;
    	while (T--)
    	{
    		int n, m; scanf("%d%d", &n, &m);
    		if (n > m) swap(n, m);
    		int sum = n * m;
    		f[0][0][0] = 1;    
    		for (int i = 0; i <= n; ++i)
    			for (int j = 0; j <= m; ++j) if (i + j) 
    				for (int k = 1; k <= sum; ++k)
    				{
    					db tot;
    					if (i == n && j == m)
    						tot = 0;
    					else
    						tot = f[i][j][k - 1] * (i * j - k + 1) * 1.0 / (sum - k + 1);	
    					if (i - 1 >= 0)
    						tot += f[i - 1][j][k - 1] * (n - i + 1) * j * 1.0 / (sum - k + 1);
    					if (j - 1 >= 0)
    						tot += f[i][j - 1][k - 1] * (m - j + 1) * i * 1.0 / (sum - k + 1);
    					if (i - 1 >= 0 && j - 1 >= 0)
    						tot += f[i - 1][j - 1][k - 1] * (n - i + 1) * (m - j + 1) * 1.0 / (sum - k + 1);
    					f[i][j][k] = tot;
    				}
    		db res = 0;
    		for (int i = 1; i <= sum; ++i)
    			res += f[n][m][i] * i;
    		printf("%.10f
    ", res);
    	}
    	return 0;
    }
    
  • 相关阅读:
    XPath使用
    正则表达式使用步骤
    os模块
    每天记十个单词
    Ubuntu下MySQL服务器,客户端安装
    使用Python3将代码打包成exe程序并添加图标的方法
    使用Python自动刷王者荣耀金币
    Ubuntu 18.04TLS命令安装谷歌浏览器
    Ubuntu 18.04TLS命令安装Python3.8
    Ubuntu 18.04TLS命令安装搜狗输入法
  • 原文地址:https://www.cnblogs.com/Dup4/p/10666575.html
Copyright © 2020-2023  润新知