• HDU 6052


    说实话不是很懂按题解怎么写,思路来源于 http://blog.csdn.net/calabash_boy/article/details/76272704?yyue=a21bo.50862.201879

    写起来倒是挺短的。

    /*
    HDU 6052 - To my boyfriend [ 分析,期望 ]  |  2017 Multi-University Training Contest 2
    题意:
    	给出一个N*M的数字矩阵
    	求子矩阵的不同数字的个数的期望
    	限制 N,M <= 100
    分析:
    	统计单点对答案的贡献
    	先定一个统计标准,比如:某种颜色对于某个矩阵的贡献由该矩阵中最右上方(先上后右)的该颜色的点所贡献
    	则单点对答案的贡献则为它所在的矩阵中 它是该颜色最右上方的那个点 的矩阵的数量
    	枚举单点复杂度O(n^2),则我们需要在O(n)的时间内求出贡献
    	
    	设矩阵形式为 [h,w]*[l,r],则对于某点(x,y),至少要求 h <= x, w >= x, l <= y, r >= y
    	对于下边界 w ,可发现没有限制,取值范围为 [x,n]
    	对于上边界 h ,为该列上与(x,y)颜色相同的上一个节点
    	对于左右边界 l,r,可发现其与上边界相关:当取上边界为h时,要求 [h,x+1] * [l,r] 中不包含同颜色的点
    		还可以发现,随着h的减小,l单调递增,r单调递减
    			即同一列只有最下边一个点有用
    	故可以先处理出每一个 h 对应的 l,r 的最小(最大)值,O(n) 枚举上边界 h (或者在枚举的时候O(1)更新)
    	
    	具体做法是维护每种颜色的每一列的最下面的点的行号
    */
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    const int N = 10005;
    int row[N][105];
    int l[105], r[105];
    int t, n, m;
    LL ans;
    void solve(int x, int y, int c)
    {
        int i, h;
        for (i = 1; i <= x; i++) l[i] = 0, r[i] = m+1;
        for (i = 1; i < y; i++) l[row[c][i]] = i;
        for (i = m; i > y; i--) r[row[c][i]] = i;
        h = row[c][y];
        for (i = x-1; i > h; i--)
            l[i] = max(l[i], l[i+1]), r[i] = min(r[i], r[i+1]);
        for (i = x; i > h; i--)
            ans += (LL)(r[i]-y) * (y-l[i]) * (n-x+1);
    }
    int main()
    {
        int i, j, col;
        scanf("%d", &t);
        while (t--)
        {
            memset(row, 0, sizeof(row));
            scanf("%d%d", &n, &m);
            ans = 0;
            for (i = 1; i <= n; i++)
                for (j = 1; j <= m; j++)
                {
                    scanf("%d", &col);
                    solve(i, j, col);
                    row[col][j] = i;
                }
            LL all = (LL)n*(n+1)/2*m*(m+1)/2;
            printf("%.9f
    ", (double)ans/all);
        }
    }
    

      

    我自倾杯,君且随意
  • 相关阅读:
    软件性能测试知识汇总
    软件功能测试知识汇总
    机器学习——KNN算法(k近邻算法)
    Shell脚本语法
    机器学习环境搭建及基础
    shell基础及变量
    查准率和召回率理解
    python中的矩阵、多维数组
    链表:反转链表
    栈和队列:生成窗口最大值数组
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/7261147.html
Copyright © 2020-2023  润新知