题目
他要我们求的是在n道题目中,有0,1,2,3…n道题目做对的概率,然后分别按隔一个空格输出对1e9+7求模后的结果,首先,我来解释一下下面几个代码的含义:
在代码中,我们先定义一个二维数组,f[2020][2020],对于f[i][j]的含义是在当前的i道题目中,恰好有j道题目做对的概率(以下所说的概率都是求模后的结果)。
const int mod=1e9+7;
(mod+1-p[i])%mod
该式的意义是第i题做错的概率。为了方便计算,我们都是假设分式a/b当中分母b的值为1,即b=1,(因为任何分式都可以化为分母为1的式子,当然,分子a可以为小数。所以由b*q%(1e9+7)=a;这里b=1,q就是我们输入的p[i],可得p[i]=kmod+a;即a=p[i]-kmod;那么求对应的错误的概率就是用1-a,即1-a=(kmod+1-p[i])%mod=(mod+1-p[i])%mod,因为分母b为1;
f[i][0]=f[i-1][0]*(mod+1-p[i])%mod;
那么,该行代码的意思就是当前有i道题目,有0道做对的概率等于i-1道题目中有0道题目做对的概率再乘以第i道题目做错的概率。
f[i][j]=(f[i-1][j]*(mod+1-p[i])%mod+f[i-1][j-1]*p[i])%mod;
所以,这个代码就不难理解了。即要求i道题目中,j道题目做对的概率,就是相当于求i-1道题目中j道题目做对的概率乘以第i道题目做错的概率,再加上i-1道题目中j-1道题目做对的概率乘以第i道题目做对的概率
全部代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll p[2020],f[2020][2020];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>p[i];
f[0][0]=1;
for(int i=1;i<=n;i++){
f[i][0]=f[i-1][0]*(mod+1-p[i])%mod;
for(int j=1;j<=i;j++){
f[i][j]=(f[i-1][j]*(mod+1-p[i])%mod+f[i-1][j-1]*p[i])%mod;
}
}
for(int i=0;i<=n;i++){
cout<<f[n][i];
if(i<n)cout<<" ";
}
return 0;
}