Atcoder Educational DP Contest I - Coins (概率DP)
阿新 • • 發佈:2020-09-12
-
題意:有\(n\)枚硬幣,每枚硬幣拋完後向上的概率為\(p[i]\),現在求拋完後向上的硬幣個數大於向下的概率.
-
題解:我們用二維的\(dp[i][j]\)來表示狀態,\(i\)表示當前拋的是第\(i\)個硬幣,\(j\)表示的是前\(i\)個硬幣中向上的個數,那麼狀態可以表示為,如果\(j=0\),那麼\(dp[i][j]=dp[i-1][j]*(1-p[i])\),否則,\(dp[i][j]=dp[i-1][j-1]*p[i]+dp[i-1][j]*(1-p[i])\).即類似01揹包的思路,當前這個狀態我選還是不選.如果選,那麼因為是\(j\)個朝上,所以要由前一枚硬幣有\(j-1\)
-
程式碼:
int n; double p[N]; double dp[4000][4000]; int main() { //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); n=read(); for(int i=1;i<=n;++i){ scanf("%lf",&p[i]); } dp[1][0]=1-p[1]; dp[1][1]=p[1]; for(int i=2;i<=n;++i){ for(int j=0;j<=i;++j){ if(j==0){ dp[i][j]=dp[i-1][j]*(1-p[i]); } else{ dp[i][j]=dp[i-1][j-1]*p[i]+dp[i-1][j]*(1-p[i]); } } } double res=0.0000000000; for(int i=(n/2)+1;i<=n;++i){ res+=dp[n][i]; } printf("%.10lf",res); return 0; }