AT_dp_i Coins题解

题目描述

设 N 是一个正的奇数。

有 N 枚硬币,每枚硬币上标有编号 1,2,…,N。对于每个 i (1≤i≤N),掷硬币 i 时,正面朝上的概率是 pi​,反面朝上的概率是 1−pi​。

太郎君把这 N 枚硬币全部投掷了一次。请计算正面朝上的硬币数多于反面朝上的硬币数的概率。

输入格式

输入以以下形式从标准输入中给出:

N p1​ p2​ … pN​

输出格式

输出正面朝上的硬币数多于反面朝上的硬币数的概率。绝对误差不超过 10−9 的结果将被视为正确。

约束条件

  • N 是奇数。
  • 1≤N≤2999
  • pi​ 是实数,精确到小数点后两位。
  • 0<pi​<1

样例解释 1

计算正面朝上的硬币数多于反面朝上的硬币数的每种情况的概率如下:

  • 当(硬币 1,硬币 2,硬币 3)=(正, 正, 正)时,概率是 0.3×0.6×0.8=0.144。
  • 当(硬币 1,硬币 2,硬币 3)=(反, 正, 正)时,概率是 0.7×0.6×0.8=0.336。
  • 当(硬币 1,硬币 2,硬币 3)=(正, 反, 正)时,概率是 0.3×0.4×0.8=0.096。
  • 当(硬币 1,硬币 2,硬币 3)=(正, 正, 反)时,概率是 0.3×0.6×0.2=0.036。

因此,正面朝上的硬币数多于反面朝上的硬币数的概率是 0.144+0.336+0.096+0.036=0.612。

样例解释 2

例如,输出 0.5000.500000001 或 0.499999999 等答案都将被视为正确。


Translated by User 735713.

显示翻译

题意翻译

输入输出样例

输入 #1复制

3
0.30 0.60 0.80

输出 #1复制

0.612

输入 #2复制

1
0.50

输出 #2复制

0.5

输入 #3复制

5
0.42 0.01 0.42 0.99 0.42

输出 #3复制

0.3821815872

思路

概率期望DP。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long n;
double f[3005][3005],a,lk=0;
int main(){
	cin>>n;
    f[0][0]=1;
    for(int i=1;i<=n;i++){
        cin>>a;
        for(int j=0;j<=i;j++){
            if(j!=0){
                f[i][j]=f[i-1][j-1]*a+f[i-1][j]*(1.00-a);
            }
            else{
                f[i][j]=f[i-1][j]*(1.00-a);
            }
        }
    }
    for(int i=n/2+1;i<=n;i++){
        lk+=f[n][i];
    }
    printf("%.10lf\n",lk);
	return 0;
}

posted @ 2025-10-22 21:05  bz02_2023f2  阅读(2)  评论(0)    收藏  举报  来源