概率dp硬币正反
Let N be a positive odd number.
There are NN coins, numbered 1,2,…,N For each i (1≤i≤N), when Coin ii is tossed, it comes up heads with probability pipi and tails with probability 1−pi.
Taro has tossed all the NN coins. Find the probability of having more heads than tails.
Constraints
- NN is an odd number.
- 1≤N≤2999
- pipi is a real number and has two decimal places.
- 0<pi<1
Input
Input is given from Standard Input in the following format:
NN p1p1 p2p2 …… pNpN
Output
Print the probability of having more heads than tails. The output is considered correct when the absolute error is not greater than 10−910−9.
Sample Input 1
3 0.30 0.60 0.80
Sample Output 1
0.612
The probability of each case where we have more heads than tails is as follows:
- The probability of having (Coin1,Coin2,Coin3)=(Head,Head,Head)(Coin1,Coin2,Coin3)=(Head,Head,Head) is 0.3×0.6×0.8=0.1440.3×0.6×0.8=0.144;
- The probability of having (Coin1,Coin2,Coin3)=(Tail,Head,Head)(Coin1,Coin2,Coin3)=(Tail,Head,Head) is 0.7×0.6×0.8=0.3360.7×0.6×0.8=0.336;
- The probability of having (Coin1,Coin2,Coin3)=(Head,Tail,Head)(Coin1,Coin2,Coin3)=(Head,Tail,Head) is 0.3×0.4×0.8=0.0960.3×0.4×0.8=0.096;
- The probability of having (Coin1,Coin2,Coin3)=(Head,Head,Tail)(Coin1,Coin2,Coin3)=(Head,Head,Tail) is 0.3×0.6×0.2=0.0360.3×0.6×0.2=0.036.
Thus, the probability of having more heads than tails is 0.144+0.336+0.096+0.036=0.6120.144+0.336+0.096+0.036=0.612.
Sample Input 2
1 0.50
Sample Output 2
0.5
Outputs such as 0.500
, 0.500000001
and 0.499999999
are also considered correct.
Sample Input 3
5 0.42 0.01 0.42 0.99 0.42
Sample Output 3
0.3821815872
题意:给N个硬币,每一个硬币扔向空中落地是正面朝上的概率是p[i] ,让求扔了N个硬币,正面的数量大于背面数量的概率
这个题就是的dp[i][j]代表的是前i个硬币时有j个是正面的概率,
所以转移方程就是:
j!=0时:dp[i][j]=1.0*dp[i-1][j-1]*p[i]+1.0*dp[i-1][j]*(1.0-p[i]);
j==0时:dp[i][j]=dp[i-1][j]*(1-p[i])
#include<iostream> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int maxn=3e3+100; double p[maxn]; double dp[maxn][maxn];//前i个硬币,有j个正面朝上的概率 int n; int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>p[i]; } dp[0][0]=1; for(int i=1;i<=n;i++){ dp[i][0]=dp[i-1][0]*(1.0-p[i]); } dp[1][1]=p[1]; for(int i=2;i<=n;i++){ for(int j=1;j<=i;j++){ dp[i][j]=1.0*dp[i-1][j-1]*p[i]+1.0*dp[i-1][j]*(1.0-p[i]); } } double ans=0; for(int i=(n/2+1);i<=n;i++){ ans+=dp[n][i]; } printf("%.9lf\n",ans); }