傳送門本題的點數很少,只有20個
考慮用二元組$s=(u,v)$表示甲在$u$點,乙在$v$點的狀態
那麼可以用$f(s)$表示狀態$s$出現的概率
不同的$f$之間的轉移就是通過邊
轉移有4種情況
對於$s=(u,v)$來說,有以下四種轉移:
轉移一,甲乙都選擇不動,此時從$s$轉移到$s$,概率為$p[u]*p[v]$
轉移二,甲動乙不動,此時從$s$轉移到$s'=(u',v)$,其中$u'$是異於$u$並與$u$相連的點,概率為$\frac*p[v]$,其中$deg[i]$表示$i$的度數
轉移三,甲不動乙動,同轉移二
轉移四,甲乙都動,此時從$s$轉移到$s'=(u',v')$,概率為$\frac\ast\frac$
寫完轉移,發現這個圖因為是聯通的,所以狀態之間的轉移會連成乙個環
這時需要用到高斯消元
構建nn個nn元方程,每個未知數對應一種狀態$s$,那麼每一項的係數就是上述的轉移概率了
需要注意的有兩點
第一,$s=(u,u)$轉移到自己是沒有概率的,因為這個狀態已經停下了,不會再轉移了
第二,出發節點的那個方程表示式的值是1,代表乙個初始元位置在出發點這裡
#include#include#include#include#include#include#define id(i,j) (i-1)*n+j
#define ll long long
using namespace std;
inline int read()
while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}double a[510][510],p[110],deg[110],go[110],ans[510];
int n,m,op1,op2,cnt;
int first[110],cnte;
struct edgee[1010];
inline void add(int u,int v);first[u]=cnte;
e[++cnte]=(edge);first[v]=cnte;
}void gauss()
}int main()
for(i=1;i<=n;i++) scanf("%lf",&p[i]),go[i]=(1.0-p[i])/deg[i];
for(u1=1;u1<=n;u1++)
for(i=first[u2];~i;i=e[i].next)
for(i=first[u1];~i;i=e[i].next)
}} }
a[id(op1,op2)][cnt+1]-=1;
gauss();
for(i=1;i<=n;i++) printf("%.6lf ",ans[id(i,i)]);
}···
bzoj 3270 博物館 高斯消元 期望轉移
乍一看比較難想到這是一道高斯消元的題目,因為概率不好轉移,得不到方程。但是反過來想,用f a,b 來表示,兩個人分別在a房間和b房間的期望。那麼這個期望是可以通過與其相連的房間的期望累加得到的 這裡的f p,q 是列舉的出發點,而p1是其對應的概率 所以可以看出乙個多元帶有係數的方程,這才引出了高斯...
bzoj3270博物館 期望概率DP
題目 設計乙個狀態表示兩個人分別在兩個點的狀態,帶個標號num i j 據此得到狀態之間轉移的關係所構成的n元方程,高斯消元求解 要注意起點的概率要 1,而且開始時兩個人在兩個點是有區分的,所以不能 a,b 和 b,a 都加 用scanf會ce,所以改成了快讀和cin 調了一天的才找到錯誤竟然是把d...
BZOJ 3270 博物館 概率 高斯消元
source實力透露做法。似乎有這麼個式子 f i,j pi p j f i,j 1 pi di p j f x,j 1 pj dj p i f i,y 1 pi di1 pjdj f x,y x adj i,y adjj 然後還有f a,b 1答案為f i,i 開n n個變數的方程組高斯消元?時間...