【概率dp】vijos 3747 随机图
没有养成按状态逐步分析问题的思维
题目描述
在一张图内,两点$i,j$之间有$p$的概率的概率生成一条边。求该图不出现大小$\ge 4$连通块的概率。
$n \le 100,答案在实数意义下$
题目分析
首先应当想到的是枚举连通块大小为$1,2,3$的点数。
有一种想法是枚举出三种点个数之后组合算出这种情况下的方案数。但是这个方案数会非常大,不取模则不现实。
于是应当dp地来看这个问题,考虑每次加一个点后概率是如何变化的。于是只需要分类讨论一下5种情况就好了。
重点在于用dp的视角看待这个问题
1 #include<bits/stdc++.h> 2 3 int n; 4 double p,q,ans,f[103][103][103]; 5 6 double qmi(double a, int b) 7 { 8 double ret = 1; 9 for (; b; b>>=1,a=a*a) 10 if (b&1) ret *= a; 11 return ret; 12 } 13 int main() 14 { 15 scanf("%d%lf",&n,&p); 16 q = (1000.0-p)/1000.0, p /= 1000.0; 17 f[1][0][0] = 1; 18 for (int ix=2,i,j,k; ix<=n; ix++) 19 for (int jx=0; jx<=ix; jx++) 20 for (int kx=0; kx+jx<=ix; kx+=2) 21 if ((ix-jx-kx)%3==0){ 22 i = jx, j = kx, k = ix-jx-kx; 23 if (i) f[i][j][k] += qmi(q, ix-1)*f[i-1][j][k]; 24 if (j) f[i][j][k] += qmi(q, ix-2)*p*(i+1.0)*f[i+1][j-2][k]; 25 if (k){ 26 f[i][j][k] += qmi(q, ix-2)*p*(j+2.0)*f[i][j+2][k-3]+qmi(q, ix-3)*p*p*(j/2+1)*f[i][j+2][k-3]+qmi(q, ix-3)*p*p*(i+2.0)*(i+1.0)/2.0*f[i+2][j][k-3]; 27 } 28 } 29 for (int i=0; i<=n; i++) 30 for (int j=0; i+j<=n; j+=2) 31 if ((n-i-j)%3==0) 32 ans += f[i][j][n-i-j]; 33 printf("%.4lf\n",1.0-ans); 34 return 0; 35 }
END