您的位置:首页 > 其它

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

2017-08-03 09:47 435 查看


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

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)

解题报告

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

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: