# 【BZOJ3925】地震后的幻想乡（ZJOI2015）-概率期望+子集状压DP

$ans=\frac{E\left[L\right]}{m+1}=\frac{1}{m+1}\sum _{x=1}^{m}x\cdot P\left(L=x\right)$

$ans=\sum _{x=1}^{m}P\left(L\ge x\right)$

$ans=\sum _{x=0}^{m-1}T\left(x\right)$

$f\left(i,j\right)=\sum _{k}\sum _{l=0}^{edge\left(k\right)}g\left(k,l\right)\cdot {C}_{edge\left(i-k\right)}^{j-l}$

$g\left(i,j\right)={C}_{edge\left(i\right)}^{j}-f\left(i,j\right)$

$ans=\frac{1}{m+1}\sum _{x=0}^{m-1}\frac{f\left(all,x\right)}{{C}_{edge\left(all\right)}^{x}}$

#include <bits/stdc++.h>
using namespace std;
int n,m,a[60],b[60],edge[1210];
double C[60][60]={0},f[1210][60],g[1210][60];

void init()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d",&a[i],&b[i]);

C[0][0]=1.0;
for(int i=1;i<=m;i++)
{
C[i][0]=1.0;
for(int j=1;j<=i;j++)
C[i][j]=C[i-1][j-1]+C[i-1][j];
}

for(int i=1;i<(1<<n);i++)
{
edge[i]=0;
for(int j=1;j<=m;j++)
if ((i&(1<<(a[j]-1)))&&(i&(1<<(b[j]-1))))
edge[i]++;
}
}

void work()
{
for(int i=1;i<(1<<n);i++)
{
for(int j=0;j<=edge[i];j++)
{
f[i][j]=0.0;
int lowbit=i&(-i);
for(int k=((i-1)&i);k;k=((k-1)&i))
if (k&lowbit)
{
for(int l=0;l<=edge[k]&&l<=j;l++)
f[i][j]+=g[k][l]*C[edge[i-k]][j-l];
}
g[i][j]=C[edge[i]][j]-f[i][j];
}
}
double ans=0.0;
for(int i=0;i<m;i++)
ans+=f[(1<<n)-1][i]/C[edge[(1<<n)-1]][i];
ans/=(double)(m+1);
printf("%.6lf",ans);
}

int main()
{
init();
work();

return 0;
}
posted @ 2018-06-24 20:58  Maxwei_wzj  阅读(91)  评论(0编辑  收藏  举报