To my boyfriend
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 977 Accepted Submission(s): 452
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
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).
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.666666667Hint6(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)
Source
题意:给出一个n*m的矩阵,每个点有一种颜色,定义矩阵的val为矩阵中不同颜色的数量,问任意一个子矩阵的val的期望为多少
解题思路:期望=所有子矩阵的val总和/子矩阵个数。子矩阵个数很明显为n*(n+1)*m*(m+1)/4。然后就是求所有子矩阵val的总和。在考虑颜色i的时候,把颜色i的点看作关键点,求出至少包含一个关键点的子矩阵个数。先排个序(行号升序,列号升序)。把每个合法的矩阵算在序最小的那个关键点头上,这样就可以保证不重复,不遗漏。在找包含第一个关键点的矩阵的时候,显然没有任何限制,只需要包含这个点就行了。找第二个关键点的矩阵的时候,不能包含第一个点……找第i个关键点决定的矩阵的时候,不能包含1..i-1这i-1个点,每次求一个点的答案的时候维护好边界即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
const LL mod = 1000000007;
int n, m;
vector<pair<int, int> > g[10010];
vector<int> a[110];
int x;
LL solve(int k)
{
LL ans = 0;
for (int i = 1; i <= n; i++) a[i].clear();
int Size = g[k].size();
for (int i = 0; i < Size; i++)
{
int x = g[k][i].first, y = g[k][i].second;
int l = 1, r = m;
bool flag = 0;
for (int i = x; i >= 1; i--)
{
int Size1 = a[i].size();
for (int j = 0; j < Size1; j++)
{
int k = a[i][j];
if (k < y) l = max(l, k + 1);
else if (k > y) r = min(r, k - 1);
else { flag = 1; break; }
}
if (flag) break;
ans += 1LL * (n - x + 1) * (y - l + 1) * (r - y + 1);
}
a[x].push_back(y);
}
return ans;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d %d", &n, &m);
for (int i = 0; i <= n * m; i++) g[i].clear();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) scanf("%d", &x), g[x].push_back(make_pair(i, j));
LL ans = 0;
for (int i = 0; i <= n * m; i++)
ans += solve(i);
printf("%.9lf\n", 1.0*ans / ((n + 1)*n*m*(m + 1) / 4));
}
return 0;
}