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


    把每一道题当作难题去做。
  • 相关阅读:
    520了,用32做个简单的小程序
    sql使用手册
    大厂Redis高并发场景设计,面试问的都在这!
    如何根据普通ip地址获取当前地理位置
    理解Python闭包,这应该是最好的例子
    520了,用32做个简单的小程序
    适合 C++ 新手学习的开源项目——在 GitHub 学编程
    寄存器(内存访问)01 零基础入门学习汇编语言13
    寄存器(CPU工作原理)07 零基础入门学习汇编语言12
    数组08 零基础入门学习C语言30
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4032019.html
Copyright © 2011-2022 走看看