CF113D Museum
题解:
不错的期望题
要求的是概率,但是两个人在同一房间相遇后不再移动了
所以我们希望利用这个特殊的性质将概率问题转化为期望问题,那么就是设$dp[i][j]$表示Petya在i房间Vasya在j房间这种状态的期望出现次数
由于$dp[x][x]$这样的情况最多出现1次,所以此时概率=期望
考虑转移
由于n只有22,所以我们先乱搞一个转移方程
设$p[i][j]$表示i到j的概率
那么$dp[i][j]=\sum\limits_{a=1}^{n} \sum\limits_{b=1}^{n} p[a][i]*p[b][j]*dp[a][b]$
这样我们就得到了$n^2$有$n^2$个未知数的方程
高斯消元一下,时间复杂度是$O(n^{2*3})$
注意:由于两个人开始时刻处在状态dp[s][t],所以此时dp[s][t]=1
所以$dp[s][t]=(\sum\limits_{a=1}^{n} \sum\limits_{b=1}^{n} p[a][s]*p[b][t]*dp[a][b])+1$
#include<bits/stdc++.h> #define maxn 100005 #define maxm 500005 #define inf 0x7fffffff #define ll long long #define rint register int #define debug(x) cerr<<#x<<": "<<x<<endl #define fgx cerr<<"--------------"<<endl #define rep(i,a,b) for(int i=a;i<=b;i++) #define dgx cerr<<"=============="<<endl #define lowbit(x) (x&(-x)) using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); while('0'>ch || ch>'9'){if(ch=='-') f=-1; ch=getchar();} while('0'<=ch && ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();} return x*f; } int n,m,f,s,b[25][25],id[25][25],cnt; double dp[1005][10][10],p[26][26],de[23],a[25],ans[26],c[625][625]; double ffabs(double x){ if(x<0) return x*-1.000000; else return x; } int main(){ cin>>n>>m>>f>>s; dp[0][f][s]=1; rep(i,1,n) rep(j,1,n) id[i][j]=++cnt; rep(i,1,m){ int x,y; cin>>x>>y; b[x][y]++; b[y][x]++; de[x]++; de[y]++; } rep(i,1,n) cin>>a[i]; rep(i,1,n){ rep(j,1,n){ if(i==j) p[i][j]=a[i]; else if(b[i][j])p[i][j]=(1-a[i])/de[i]; } } rep(i,1,n){ rep(j,1,n){ if(i==f && j==s) c[id[i][j]][cnt+1]=-1; c[id[i][j]][id[i][j]]=-1; rep(k,1,n){ rep(l,1,n){ if(k==l) continue; c[id[i][j]][id[k][l]]+=p[k][i]*p[l][j]; } } } } rep(i,1,cnt){ int pos=i; rep(j,i+1,cnt){ if(ffabs(c[j][i])>ffabs(c[pos][i])) pos=j; } rep(j,1,cnt+1) swap(c[pos][j],c[i][j]); /*rep(ii,1,cnt){ rep(jj,1,cnt+1) cout<<c[ii][jj]<<" ";cout<<endl; }*/ if(!c[i][i]) return 0; rep(j,i+1,cnt+1) c[i][j]/=c[i][i]; rep(k,1,cnt) rep(j,1,cnt+1) if(j!=i && k!=i) c[k][j]=c[k][j]-(c[k][i]*c[i][j]); } rep(i,1,cnt){ if(i%n==int(i/n)+1) ans[i%n]=c[i][cnt+1]; } ans[n]=c[cnt][cnt+1]; rep(i,1,n) printf("%.8lf\n",ans[i]); return 0; }