日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【BZOJ3640】JC的小苹果 概率DP+高斯消元

發布時間:2023/12/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【BZOJ3640】JC的小苹果 概率DP+高斯消元 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【BZOJ3640】JC的小蘋果

Description

???讓我們繼續JC和DZY的故事。

????“你是我的小丫小蘋果,怎么愛你都不嫌多!”

????“點亮我生命的火,火火火火火!”

????話說JC歷經艱辛來到了城市B,但是由于他的疏忽DZY偷走了他的小蘋果!沒有小蘋果怎么聽歌!他發現邪惡的DZY把他的小蘋果藏在了一個迷宮里。JC在經歷了之前的戰斗后他還剩下hp點血。開始JC在1號點,他的小蘋果在N號點。DZY在一些點里放了怪獸。當JC每次遇到位置在i的怪獸時他會損失Ai點血。當JC的血小于等于0時他就會被自動彈出迷宮并且再也無法進入。

????但是JC迷路了,他每次只能從當前所在點出發等概率的選擇一條道路走。所有道路都是雙向的,一共有m條,怪獸無法被殺死。現在JC想知道他找到他的小蘋果的概率。

????P.S.大家都知道這個系列是提高組模擬賽,所以這是一道送分題balabala

Input

第一行三個整數表示n,m,hp。接下來一行整數,第i個表示jc到第i個點要損失的血量。保證第1個和n個數為0。接下來m行每行兩個整數a,b表示ab間有一條無向邊。

Output

????僅一行,表示JC找到他的小蘋果的期望概率,保留八位小數。

Sample Input

3 3 2
0 1 0
1 2
1 3
2 3

Sample Output

0.87500000

HINT

對于100%的數據 2<=n<=150,hp<=10000,m<=5000,保證圖聯通。

題解:如果沒有Ai=0,直接DP,如果hp很小,直接高斯消元,但是都有,所以用DP+高斯消元。

發現,方程組中只有Ai=0的點有系數,Ai!=0的都可以直接拿過來變成常數項,所以每次我們的方程組只有一列是變化的,所以我們將方程組表示成Ax=b,x=A-1b。x和b都是列向量。所以我們只需要預處理出A的逆,然后每次O(n2)乘一下就行了。

矩陣求逆的方法:先將(A|I)拼一起,然后通過行變換將左邊的A消成I,右邊剩下的就是A-1

?

#include <cstdio> #include <cstring> #include <iostream> #include <cmath> using namespace std; int n,m,hp; int dam[160],pa[5010],pb[5010],d[160]; double f[160][10000],B[160],ans; struct M {double v[160][160];M (){memset(v,0,sizeof(v));}double* operator [](int x) {return v[x];}void I(){for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) v[i][j]=(i==j)?1:0;}M getinv(){int i,j,k;M re;double t;re.I();for(i=1;i<=n;i++){for(j=i;j<=n;j++) if(fabs(v[j][i])>fabs(v[i][i])) for(k=1;k<=n;k++)swap(v[i][k],v[j][k]),swap(re[i][k],re[j][k]);t=v[i][i];for(j=1;j<=n;j++) v[i][j]/=t,re[i][j]/=t;for(j=1;j<=n;j++) if(i!=j){t=v[j][i];for(k=1;k<=n;k++) v[j][k]-=t*v[i][k],re[j][k]-=t*re[i][k];}}return re;}void operator * (int x){for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][x]+=v[i][j]*B[j];} }; M A,A1; int rd() {int ret=0,f=1; char gc=getchar();while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();return ret*f; } int main() {n=rd(),m=rd(),hp=rd();int i,j;for(i=1;i<=n;i++) dam[i]=rd();for(i=1;i<=m;i++){pa[i]=rd(),pb[i]=rd();d[pa[i]]++;if(pa[i]!=pb[i]) d[pb[i]]++;}for(i=1;i<=m;i++){if(!dam[pb[i]]) A[pb[i]][pa[i]]-=1.0/d[pa[i]];if(pa[i]==pb[i]) continue;if(!dam[pa[i]]) A[pa[i]][pb[i]]-=1.0/d[pb[i]];}for(i=1;i<=n;i++) A[i][n]=0;for(i=1;i<=n;i++) A[i][i]++;A1=A.getinv();for(j=hp;j;j--){for(i=1;i<=n;i++) B[i]=0;if(j==hp) B[1]=1;else for(i=1;i<=m;i++){if(dam[pb[i]]&&dam[pb[i]]+j<=hp&&pa[i]!=n) B[pb[i]]+=f[pa[i]][j+dam[pb[i]]]*1.0/d[pa[i]];if(pa[i]==pb[i]) continue;if(dam[pa[i]]&&dam[pa[i]]+j<=hp&&pb[i]!=n) B[pa[i]]+=f[pb[i]][j+dam[pa[i]]]*1.0/d[pb[i]];}A1*j,ans+=f[n][j];}printf("%.8lf",ans);return 0; }

?

轉載于:https://www.cnblogs.com/CQzhangyu/p/7054760.html

總結

以上是生活随笔為你收集整理的【BZOJ3640】JC的小苹果 概率DP+高斯消元的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。