2020牛客寒假算法基础集训营2 C.算概率

2020牛客寒假算法基础集训营2 C.算概率

题目描述

牛牛刚刚考完了期末,尽管 牛牛 做答了所有 \text{}nn 道题目,但他不知道有多少题是正确的。
不过,牛牛 知道第 i i 道题的正确率是 p i p_i
牛牛 想知道这 n 题里恰好有 0 , 1 , , n 0,1,\dots,n 题正确的概率分别是多少,对 1 0 9 + 7 10^9+7 取模。

输入描述:

第一行,一个正整数 n 。
第二行,\text{}nn 个整数 p 1 , p 2 , , p n p_1,p_2,\dots,p_n ,在模 1 0 9 + 7 10^9+7 意义下给出。
保证 1 n 2000 1\leq n\leq 2000

输出描述:

输出一行 n+1 个用空格隔开的整数表示答案(对 1 0 9 + 7 10^9+7 取模)。

示例1

输入

1
500000004

输出

500000004 500000004

典型的概率DP,用 d p i , j dp_{i,j} 表示前 i i 道题对 j j 道的概率,不难求出状态转移方程:
1. j = 0 d p 0 , 0 = 1 , d p i , 0 = d p i 1 , 0 ( 1 p ) j=0时,dp_{0,0}=1,dp_{i,0}=dp_{i-1,0}*(1-p)
2. j > 0 d p i , j = d p i 1 , j ( 1 p ) + d p i 1 , j 1 p j>0时,dp_{i,j}=dp_{i-1,j}*(1-p)+dp_{i-1,j-1}*p
假设某题正确概率为 p p ,则错误概率为 1 p 1-p ,有人问 1 p 1-p 为负数怎么办,负数取模很简单,就是 ( 1 p + m o d ) (1-p+mod) % m o d mod ,AC代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e3+5;
const int mod=1e9+7;
ll n,p[N],dp[N][N];
int main()
{
    cin>>n;
    for(ll i=1;i<=n;i++) cin>>p[i];
    dp[0][0]=1;
    for(ll i=1;i<=n;i++){
        dp[i][0]=dp[i-1][0]*(1-p[i]+mod)%mod;
        for(ll j=1;j<=n;j++)
            dp[i][j]=(dp[i-1][j]*(1-p[i]+mod)%mod+dp[i-1][j-1]*p[i]%mod)%mod;
    }
    for(ll i=0;i<=n;i++)
        cout<<dp[n][i]<<" ";
    return 0;
}
发布了288 篇原创文章 · 获赞 14 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_43765333/article/details/104219811