Scout YYF I(矩陣優化dp)
阿新 • • 發佈:2019-02-14
題目:
題意:
主人公有p的機率走一步,1-p的機率走兩步,主人公一開始在格子1,給出地雷的位置,請問安全通過的概率是多少
題解:
概率與期望第一彈,但是這道題體現的基本是矩陣優化思想,那就當是矩陣題做一下
dp[i]表示到第i個格子安全的概率,不難發現:dp[i]=dp[i-1]*p+dp[i-2]*(1-p)
但是這樣i太大了,我們不如矩陣優化一下
dp[i] | p ,1-p |n-1 dp[1]
=| | *
dp[i-1] | 1 , 0 | dp[0]
程式碼:
#include <cstdio> #include <algorithm> #include <iostream> #include <cstring> using namespace std; struct hh { double cr[3][3]; }; int a[12]; double p; hh work(hh a,hh b) { hh c; int i,j,k; memset(c.cr,0,sizeof(c.cr)); for (i=1;i<=2;i++) for (j=1;j<=2;j++) for (k=1;k<=2;k++) c.cr[i][j]=(c.cr[i][j]+a.cr[i][k]*b.cr[k][j]); return c; } double pow(int pp) { hh x,ans; memset(ans.cr,0,sizeof(ans.cr)); x.cr[1][1]=p; x.cr[1][2]=1-p; x.cr[2][1]=1; x.cr[2][2]=0; ans.cr[1][1]=1; ans.cr[2][1]=0; for (;pp;pp>>=1,x=work(x,x)) if (pp&1) ans=work(ans,x); return ans.cr[1][1]; } int main() { int n,i; while (~scanf("%d%lf",&n,&p)) { for (i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1); double rr=1.0; for (i=1;i<=n;i++) rr*=(1-pow(a[i]-a[i-1]-1)); printf("%.7f\n",rr); } }