hdu 6052 To my boyfriend(枚举+容斥)

来源:互联网 发布:饺子 知乎 编辑:程序博客网 时间:2024/06/05 06:30

To my boyfriend

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 952    Accepted Submission(s): 440


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
12 31 2 12 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)


解题报告


算出每一个点对包含他的矩阵的贡献,麻烦的是如何排除重复的情况,按照从上到下从左到右的顺序计算每一个点,枚举上边界同时维护左右边界计算方法数;


#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<vector>#include<cmath>#include<queue>#include <bits/stdc++.h>using namespace std;const int N = 35050+7;typedef  long long LL;const LL mod = 1e9+7;int color[110][110];int n, m;LL solve(int x,int y){    LL ans=0;    int L=1, R=m, l, r;    for(int i=x; i>=1; i--)    {        if(i!=x&&color[i][y]==color[x][y]) break;        int j, k;        for(j=y-1; j>=L; j--)            if(color[i][j]==color[x][y])            {                j++;                break;            }        L=max(L,j);        if(i==x)        {            ans+=(n-x+1)*(m-y+1)*(y-L+1);            continue;        }        for(k=y+1; k<=R; k++)            if(color[i][k]==color[x][y])            {                k--;                break;            }        R=min(R,k);        ans+=(LL)(n-x+1)*(R-y+1)*(y-L+1);    }    //cout<<ans<<endl;    return ans;}int main(){    int t;    scanf("%d", &t);    while(t--)    {        scanf("%d %d", &n, &m);        for(int i=1; i<=n; i++)            for(int j=1; j<=m; j++)                scanf("%d", &color[i][j]);        LL ans=0, mi=0, mx=n*(n+1)*m*(m+1);        for(int i=1; i<=n; i++)            for(int j=1; j<=m; j++)                mi+=solve(i,j);        printf("%.9f\n",4.0*mi/mx);    }    return 0;}










原创粉丝点击