题目:http://acm.hdu.edu.cn/showproblem.php?pid=5570
num[j] 表示 颜色为 j 的球的个数,题目要求 sum(num[j]^2) 0 < j <= m
b[i][j] 表示 i 球颜色为 j 的概率。不同球的颜色是互不影响的,所以直接相加就是 个数 ,所以
num[j] = sum(b[i][j]) = b[1][j] + b[2][j] .... + b[n][j] (0 < i <= n)
然后求 num[j]^2 。 如果直接 对上面的式子平方 显然是错误的。
因为 num[j]^2 可以 看作 俩组 球 能组成几对,如:
球编号: 1 2 3 4
球编号: 5 6 7 8 1号球能和5 6 7 8 组对即1×4,2号也一样1×4,所以一共 4^2。如果换成概率就是1好球的概率乘上下面每个球的概率,加上2号乘......
而我们 num[j]^2 中 的 两组球 是 相同的 两组
球编号: 1 2 3 4
球编号: 1 2 3 4 上面的1和下面的2 组对时仍然是1的概率乘上2的概率,但是 1 和 1 组队时,却不是。 当我们确定球1为颜色j时,下面的球1已经确定了为颜色j,即其概率为1
因此 num[j]^2 = b[1][j]*1 + sum(b[1][j]*b[i][j]) (0<i<=n,i != 1) + b[2][j]*1 + sum(b[2][j]*b[i][j]) (0<i<=n,i != 2)..... b[n][j]*1 + sum(b[n][j]*b[i][j])(0<i<=n,i != n)
在每个sum 中 都可以提出 公因式, 第一个提出 b[1][j] 第二个提出b[2][j].....第n个提出b[n][j]
num[j]^2 = b[1][j]*1 + sum(b[i][j])*b[1][j] (0<i<=n,i != 1) .....+b[n][j]*1 + sum(b[n][j])*b[n][j] (0<i<=n,i != n)
因此可以令 sump = sum(b[i][j]) (0<i<=n)
则 num[j]^2 = b[1][j]*1 + (sump - b[1][j])*b[1][j] .....+b[n][j]*1 + (sump-b[n][j])*b[n][j]
ans = sum(num[j]^2) (0 < j <= m)#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define MS(x,y) memset(x,y,sizeof(x))
void fr(){freopen("t.txt","r",stdin);}
typedef long long LL;
int _map[1005][1005],dp[1005][1005];
int calc(int x,int y)
{
int i,j,minn = 1<<30;
if(y-2>0)minn = min(minn,dp[x][y-2]+_map[x][y]*_map[x][y-1]);
if(x-1>0&&y-1>0)
{
minn = min(minn,dp[x-1][y-1]+_map[x][y-1]*_map[x][y]);
minn = min(minn,dp[x-1][y-1]+_map[x-1][y]*_map[x][y]);
}
if(x-2>0)minn = min(minn,dp[x-2][y]+_map[x-1][y]*_map[x][y]);
return minn;
}
int a[1005][1005];
double b[1005][1005];
int main()
{
// fr();
int n,m,i,j,sum[1005];
double ans;
while(~scanf("%d%d",&n,&m))
{
MS(sum,0);
ans = 0;
for(i = 1; i <= n; i++)
{
for(j = 1; j <= m; j++)
{
scanf("%d",&a[i][j]);
sum[i]+= a[i][j];
}
for(j = 1; j <= m; j++)b[i][j] = a[i][j]*1.0/sum[i];
}
for(j = 1; j <= m; j++)
{
double sump = 0;
for(i = 1; i <= n; i++) sump+=b[i][j];
for(i = 1; i <= n; i++) ans += b[i][j] + (sump - b[i][j])*b[i][j];
}
printf("%.2lf\n",ans);
}
return 0;
}