• 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;
    }


    把每一道题当作难题去做。
  • 相关阅读:
    六类人最适合做程序员!不善于撩妹的人竟然当选...哈哈
    20170926-构建之法:现代软件工程-阅读笔记
    Android Studio新建类头部注释和添加函数注释模板及快捷键
    android AysncTask使用
    Android Studio配置git,实现项目在github上的版本同步
    avloadingindicatorview 使用解析
    retrofit 基础使用
    retrofit 使用解析
    关于HTTP
    单例模式
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4032019.html
Copyright © 2020-2023  润新知