【多校訓練】hdu 6052 To my boyfriend 計數

Problem Description
Dear Liao

I never forget the moment I met with you. You carefully asked me: "I have a very difficult problem. Can you teach me?". I replied with a smile, "of course". You replied:"Given a matrix, I randomly choose a sub-matrix, what is the expectation of the number of **different numbers** it contains?"

Sincerely yours,
Guo
 

Input
The first line of input contains an integer T(T≤8) indicating the number of test cases.
Each case contains two integers, n and m (1≤n, m≤100), the number of rows and the number of columns in the grid, respectively.
The next n lines each contain m integers. In particular, the j-th integer in the i-th of these rows contains g_i,j (0≤ g_i,j < n*m).
 

Output
Each case outputs a number that holds 9 decimal places.
 

Sample Input
1 2 3 1 2 1 2 1 2
 

Sample Output
1.666666667
Hint
6(size = 1) + 14(size = 2) + 4(size = 3) + 4(size = 4) + 2(size = 6) = 30 / 18 = 6(size = 1) + 7(size = 2) + 2(size = 3) + 2(size = 4) + 1(size = 6)

題意:

給出一個n*m(1<=n,m<=100)的矩陣,每個矩陣元素有一個顏色值ai(0<=ai<=10000),現在定義一個子矩陣的value爲子矩陣中不同顏色的數量,求子矩陣value的期望


思路:

這類計數題一般都是考慮每種顏色的貢獻值,以及每個點的邊界。

枚舉每種顏色,單獨枚舉其中的每個點。考慮這個點的可以生成矩陣的上下左右邊界,然後計算貢獻。

推薦一篇講的十分詳細的博客:http://blog.csdn.net/calabash_boy/article/details/76272704

具體看代碼:

//
//  main.cpp
//  6052
//
//  Created by zc on 2017/9/4.
//  Copyright © 2017年 zc. All rights reserved.
//

#include <iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#define ll long long 
using namespace std;
const int N=110;
int n,m,mp[N][N];
vector<pair<int,int> >r[N*N];
bool v[N][N];

int main(int argc, const char * argv[]) {
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n*m;i++) r[i].clear();
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            {
                scanf("%d",&mp[i][j]);
                r[mp[i][j]].push_back(make_pair(i,j));
            }
        for(int i=0;i<=n*m;i++)
            if(!r[i].empty())
                sort(r[i].begin(),r[i].end());
        ll ans=0;
        for(int col=0;col<=n*m;col++)
        {
            if(r[col].empty())   continue;
            memset(v,0,sizeof(v));
            for(int i=0;i<r[col].size();i++)
            {
                pair<int,int> t=r[col][i];
                int x=t.first,y=t.second;
                for(int j=x;j>=0&&v[j][y]==0;j--)
                {
                    int l,r;
                    for(l=y;l>=0&&v[j][l]==0;l--);
                    for(r=y;r<m&&v[j][r]==0;r++);
                    ans+=(ll)(n-x)*(y-l)*(r-y);
                    v[j][y]=1;
                }
            }
        }
        printf("%.9f\n",(double)ans/(n*(n+1)*m*(m+1)/4));
    }
}

發佈了323 篇原創文章 · 獲贊 119 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章