zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Android--adb
    Android 爬坑之路
    Android倒计时实现
    Android Studio常用设置
    Java Web开发——MySQL数据库的安装与配置
    DOS命令(系统错误5,拒绝访问)的解决方法
    Java EE开发环境——MyEclipse2017破解 和 Tomcat服务器配置
    设计模式-工厂模式
    设计模式-简单工厂模式
    设计模式简介
  • 原文地址:https://www.cnblogs.com/Dup4/p/10666575.html
Copyright © 2011-2022 走看看