zoukankan      html  css  js  c++  java
  • ACM学习历程——ZOJ 3822 Domination (2014牡丹江区域赛 D题)(概率,数学递推)

    Description

    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
    


    这个题目可以设一个概率函数p(i, j, k)表示用k个石子覆盖i行j列的概率,可以先算出所有的p值,然后就是概率乘天数加和求出期望。
    然而对于概率的递推,可以考虑以下四种情况:
    1、由p(i-1, j-1, k-1)在没有被覆盖的行切其列没有被覆盖的格子里放上一个石子;
    2、由p(i-1, j, k-1)在没有被覆盖的一行放上一个石子;
    3、由p(i, j-1, k-1)在没有被覆盖的一列放上一个石子;
    4、由p(i-1, j-1, k-1)在被覆盖过行且列的格子里放上一个石子;
    不过需要注意,在计算p(n, m, ?)时不需要加上第四项。
    然而对于每一种都有其自己的概率系数,这个系数在代码里会有体现。(满足条件的格子数目/剩余总格子数目)ps:关键在于找满足条件的格子数目。


    代码:
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <set>
    #include <map>
    #include <vector>
    #include <string>
    #include <queue>
    #define inf 0x3fffffff
    #define esp 1e-10
    #define N 55
    
    using namespace std;
    
    double p[N][N][N*N];
    
    double qt (int n, int m)
    {
        memset (p, 0, sizeof(p));
        int len = n*m;
        p[0][0][0] = 1;
        for (int i = 1; i <= n; ++i)
        {
            for (int j = 1; j <= m; ++j)
            {
                for (int k = 1; k <= len; ++k)
                {
                    p[i][j][k] = p[i-1][j-1][k-1]/(n*m-k+1)*(n-i+1)*(m-j+1);
                    p[i][j][k] += p[i-1][j][k-1]/(n*m-k+1)*(n-i+1)*j;
                    p[i][j][k] += p[i][j-1][k-1]/(n*m-k+1)*i*(m-j+1);
                    if (i != n || j != m)
                        p[i][j][k] += p[i][j][k-1]/(n*m-k+1)*(i*j-k+1);
                }
            }
        }
        double ans = 0;
        for (int k = 0; k <= len; ++k)
            ans += p[n][m][k]*k;
        return ans;
    }
    
    int main()
    {
        //freopen ("test.txt", "r", stdin);
        int T;
        scanf ("%d", &T);
        for (int times = 0; times < T; ++times)
        {
            int n, m;
            scanf ("%d%d", &n, &m);
            printf ("%.10lf
    ", qt (n, m));
        }
        return 0;
    }


    把每一道题当作难题去做。
  • 相关阅读:
    采样定理
    空间谱专题03:时空特性与采样定理
    常见的矩阵形式
    【Windows】XShell中使用小键盘和ALT键(作Meta键),使BackSpace正常
    【Linux】Ubuntu13.10搭建gitlab报错信息及解决
    〖Android〗ant build android project, setting android.jar precedence
    〖Linux〗使用命令行切换触摸板的状态on/off/toggle
    【Android】ant编译aidl的错误
    【Android】源码external/目录中在编译过程中生成的文件列表
    〖Linux〗实时更新 hosts 文件的脚本
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4032019.html
Copyright © 2011-2022 走看看