hdu 5570 期望 概率详解

题目: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;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值