balls
Accepts: 19
Submissions: 55
Time Limit: 6000/3000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
有n个球,共有m种颜色,第i个球的颜色为j的概率为ai,1+ai,2+...+ai,mai,j。 对于第i种颜色,若有x个球,对答案的贡献为x2。 问答案的期望。
输入描述
若干组数据(大概5组)。 每组数据第一行两个整数n(1≤n≤1000),m(1≤m≤1000)。 接下来n行每行m个数表示ai,j(1≤ai,j≤100)
输出描述
对于每组数组,输出一行表示答案,保留两位小数。
输入样例
2 2 1 1 3 5 2 2 4 5 4 2 2 2 2 4 1 4
输出样例
3.00 2.96 3.20
val[i][j]表示第i个球颜色为j的概率。那么第i个球颜色为j的期望E[x[i][j]]=val[i][j]*1+(1-val[i][j])*0=val[i][j]
c[i]表示颜色为i的球的个数。题目要求的是 sum(E[c[i]^2]) i的值从1到m。
从最简单的来看 如果要求的是E[c[i]],那么它等于E[(x[1][i]+x[2][i]...+x[n][i])]
现在要求的是E[c[i]^2]=E[(x[1][i]+x[2][i]...+x[n][i])^2]。
里面展开的话就是任意两个相乘,拿出其中一项来看 E[x[k1][i]*x[k2][i]]
若k1==k2,那这个等式等于=val[k1][i]
若k1!=k2,那这个等式等于=val[k1][i]*val[k2][i]
求和即是结果了。
代码:
#pragma warning(disable:4996)
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 1005;
int n, m;
double val[maxn][maxn];
int main()
{
//freopen("i.txt", "r", stdin);
//freopen("o.txt", "w", stdout);
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = 1; i <= n; i++)
{
double sum = 0;
for (int j = 1; j <= m; j++)
{
scanf("%lf", &val[i][j]);
sum += val[i][j];
}
for (int j = 1; j <= m; j++)
{
val[i][j] = val[i][j] / sum;
}
}
double ans = 0;
for (int i = 1; i <= m; i++)
{
double sum = 0;
for (int j = 1; j <= n; j++)
{
sum += val[j][i];
ans += val[j][i];
ans -= val[j][i] * val[j][i];
}
ans += (sum*sum);
}
printf("%.2lf\n", ans);
}
//system("pause");
return 0;
}