【BZOJ3925】地震后的幻想乡(期望概率DP,状压DP)
题意:给定一张点数不超过10的无向连通图,每条边有一个[0,1]之间的随机权值,求最小生成树上最大边的期望值
提示:对于n个[0,1]之间的随机变量x1,x2,...,xn,第k小的那个的期望值是k/(n+1)。
思路:From http://www.cnblogs.com/ihopenot/p/6606665.html
题目后面的小提示很有用,问题实际上就转化为了求用k条边使原图恰好联通的概率。
但是恰好联通是个很蛋疼的条件,所以我们稍微把问题再变一变,我们去求用k条边原图仍不联通的概率
设f[S][k]为用了k条边原图的子集S仍不联通的方案数,总方案数显然为C[S中的边数][k]。
那么这样的话,每种边数对答案的贡献就是(f[S][k]/C[S][k])*(1/(m+1))
因为每条边无法联通图的话必然会让下一条边的期望增加1/(m+1)
那么关键就是求解 f
对于不连通图的计数可以固定某个点,枚举连通块,去不重不漏地计数
所以我们的 f 用这种方法去转移
静待Round 2爆炸退役
1 var dp:array[0..3000,0..200]of extended; 2 a:array[1..20,1..20]of longint; 3 cnt:array[0..3000]of longint; 4 c:array[0..3000,0..3000]of extended; 5 n,m,i,sta,k,t,j,x,y:longint; 6 ans:extended; 7 8 function lowbit(x:longint):longint; 9 begin 10 exit(x and (-x)); 11 end; 12 13 begin 14 assign(input,'bzoj3925.in'); reset(input); 15 assign(output,'bzoj3925.out'); rewrite(output); 16 read(n,m); 17 for i:=1 to m do 18 begin 19 read(x,y); 20 a[x,y]:=1; a[y,x]:=1; 21 end; 22 c[0,0]:=1; 23 for i:=1 to m do 24 begin 25 c[i,0]:=1; 26 for j:=1 to i do c[i,j]:=c[i-1,j-1]+c[i-1,j]; 27 end; 28 for sta:=0 to (1<<n)-1 do 29 begin 30 for i:=1 to n do 31 for j:=1 to n do 32 if (a[i,j]=1)and 33 (sta and (1<<(i-1))>0)and(sta and (1<<(j-1))>0) then inc(cnt[sta]); 34 cnt[sta]:=cnt[sta]>>1; 35 end; 36 for sta:=0 to (1<<n)-1 do 37 begin 38 t:=lowbit(sta); 39 k:=sta and (sta-1); 40 while k>0 do 41 begin 42 if k and t=0 then begin k:=sta and (k-1); continue; end; 43 for i:=0 to cnt[sta] do 44 for j:=0 to i do 45 dp[sta,i]:=dp[sta,i]+(c[cnt[k],j]-dp[k,j])*c[cnt[sta xor k],i-j]; 46 k:=sta and (k-1); 47 end; 48 end; 49 for i:=0 to cnt[(1<<n)-1] do ans:=ans+dp[(1<<n)-1,i]/c[cnt[(1<<n)-1],i]; 50 ans:=ans/(m+1); 51 writeln(ans:0:6); 52 53 close(input); 54 close(output); 55 end.
null