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;
    }
    
  • 相关阅读:
    Linux下进程间通信的六种机制详解
    Android HAL实例解析
    socket函数
    Linux 线程浅析
    Android WiFi开发教程(一)——WiFi热点的创建与关闭
    Android蓝牙开发教程(三)——蓝牙设备相互通讯
    python数据分析入门学习笔记儿
    Oracle触发器详解
    电商检索系统总结——功能篇
    Linux内核中等待队列的几种用法
  • 原文地址:https://www.cnblogs.com/Dup4/p/10666575.html
Copyright © 2011-2022 走看看