ball
这
题
主
要
运
用
一
个
很
巧
妙
的
转
换
,
显
然
,
求
期
望
,
由
于
n
和
m
,
所
以
我
们
应
该
用
二
维
数
组
维
护
x
2
的
期
望
这题主要运用一个很巧妙的转换,显然,求期望,由于n和m,所以我们应该用二维数组维护x^2的期望
这题主要运用一个很巧妙的转换,显然,求期望,由于n和m,所以我们应该用二维数组维护x2的期望
但
x
2
的
期
望
不
好
求
,
以
我
们
考
虑
补
足
贡
献
,
再
引
入
一
个
新
的
量
(
x
)
的
期
望
但x^2的期望不好求,以我们考虑补足贡献,再引入一个新的量(x)的期望
但x2的期望不好求,以我们考虑补足贡献,再引入一个新的量(x)的期望
定义f[i][j]为前i个,颜色为j的期望个数x,g[i][j]为前i,颜色为j的期望个数平方x^2
前置知识
1. 期 望 有 实 际 意 义 , 实 际 意 义 只 像 物 理 中 的 F , G . . . . . . . 一 样 有 实 际 意 义 , 而 不 是 像 数 学 中 的 方 程 的 解 x 一 样 1. 期望有实际意义,实际意义只像物理中的F,G.......一样有实际意义,而不是像数学中的方程的解x一样 1.期望有实际意义,实际意义只像物理中的F,G.......一样有实际意义,而不是像数学中的方程的解x一样
先 预 处 理 出 p [ i ] [ j ] 表 示 第 i 个 为 j 的 概 率 先预处理出p[i][j]表示第i个为j的概率 先预处理出p[i][j]表示第i个为j的概率
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
p[i][j]=(double)a[i][j]/sum[i];
}
}
f
[
i
]
[
j
]
=
f
[
i
−
1
]
[
j
]
+
p
[
i
]
[
j
]
(
即
已
经
有
f
[
i
−
1
]
[
j
]
个
,
有
p
[
i
]
[
j
]
的
几
率
多
一
个
没
有
其
它
有
贡
献
的
情
况
)
f[i][j]=f[i-1][j]+p[i][j](即已经有f[i-1][j]个,有p[i][j]的几率多一个没有其它有贡献的情况)
f[i][j]=f[i−1][j]+p[i][j](即已经有f[i−1][j]个,有p[i][j]的几率多一个没有其它有贡献的情况)
g
[
i
]
[
j
]
=
g
[
i
−
1
]
[
j
]
+
(
)
,
即
原
来
有
的
平
方
可
以
保
留
,
然
后
考
虑
本
次
的
a
i
,
j
,
所
以
肯
定
要
乘
一
个
概
率
p
,
贡
献
为
2
∗
f
[
i
−
1
]
[
j
]
+
1
,
因
为
(
x
+
1
)
2
等
于
x
2
+
2
∗
x
+
1
,
x
2
=
x
2
,
即
多
选
一
个
的
贡
献
为
2
∗
x
+
1
g[i][j]=g[i-1][j]+(),即原来有的平方可以保留,然后考虑本次的a_{i,j},所以肯定要乘一个概率p,贡献为2*f[i-1][j]+1,因为(x+1)^2等于x^2+2*x+1,x^2=x^2,即多选一个的贡献为2*x+1
g[i][j]=g[i−1][j]+(),即原来有的平方可以保留,然后考虑本次的ai,j,所以肯定要乘一个概率p,贡献为2∗f[i−1][j]+1,因为(x+1)2等于x2+2∗x+1,x2=x2,即多选一个的贡献为2∗x+1
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1010;
int n,m,a[N][N],sum[N];
double p[N][N],g[N][N],f[N][N];
int main(){
while(~scanf("%d%d",&n,&m)){
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
sum[i]=sum[i]+a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
p[i][j]=(double)a[i][j]/sum[i];
}
}
for(int j=1;j<=m;j++){f[1][j]=p[1][j];g[1][j]=p[1][j];}
for(int i=2;i<=n;i++){
for(int j=1;j<=m;j++){
f[i][j]=f[i-1][j]+p[i][j];
g[i][j]=g[i-1][j]+p[i][j]*(2*f[i-1][j]+1);
}
}
double ans=0;
for(int j=1;j<=m;j++){ans+=g[n][j];}
printf("%.2lf\n",ans);
}
}