题目:
随机图
(random.cpp/c/pas)
【问题描述】
BG 为了造数据,随机生成了一张�个点的无向图。他把顶点标号为1~�。
根据BG 的随机算法,对于一个点对�, �(1 ≤ � < � ≤ �),它有�‰(千分之�)的概率成为
这张图中的一条边� − �。不同的边出现的概率是相互独立的。
为了保证数据的强度,BG要求生成的图中至少要有一个大于等于 4的连通块。于是他
想知道,在不做任何改进的情况下,根据他的算法造出强数据的概率是多少。
【输入】
输入文件名为random.in。
共一行两个整数�, �,中间用一个空格隔开,表示图的点数和边在图上的概率。
【输出】
输出文件名为random.out。
输出共一行一个实数,表示所求的概率。结果保留4 位小数。 【输入输出样例1】
random.in random.out
3 123
0.0000
【输入输出样例2】
random.in random.out
4 500
0.5938
题解:�
概率DP方程
�[�+1][�−1][�+1],乘上系�·(1−�)�
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N=105; double dp[N][N][N],p,ans=1; double c[N][2]; int n; inline void pre() { for(int i=1;i<=n;i++) c[i][1]=i; for(int i=2;i<=n;i++) for(int j=2;j<=n;j++) c[i][j]=c[i-1][j]+c[i-1][j-1]; } int main() { scanf("%d",&n); cin>>p; p=p/1000; pre(); dp[0][0][0]=1; for(int i=0;i<=n;i++) for(int j=0;j<=n/2;j++) for(int k=0;k<=n/3;k++) { int l=(i-2*j-3*k); dp[i+1][j][k]+=dp[i][j][k]*pow(1-p,i); dp[i+1][j+1][k]+=dp[i][j][k]*pow(1-p,i-1)*l*p; dp[i+1][j][k+1]+=dp[i][j][k]*c[l][2]*pow(1-p,i-2)*p*p; dp[i+1][j-1][k+1]+=dp[i][j][k]*pow(1-p,i-1)*2*j*p; dp[i+1][j-1][k+1]+=dp[i][j][k]*pow(1-p,i-2)*j*p*p; } for(int j=0;j<=n/2;j++) for(int k=0;k<=n/3;k++) ans-=dp[n][j][k]; printf("%0.4lf",ans); return 0; }