/* 刚读完题 呀,这不是个数学题吗 二项分布呀 求出小红每题得分的概率,然后用二项分布的公式 然后,思路很清晰了,先把大体框架写完.... 写完主函数后 发现 C(50,x) 这组合数怎么求QwQ 百分之百爆long long啊 前半部分组合数爆long long,后半部分乘方损精度 这做法大概没救了
*/
那份没救了的代码
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int n,A,q; int tot; double double_pow(double a,int b){ double mul=1.0; while(b){ if(b) mul=mul*a; a=a*a; } return mul; } int main(){ scanf("%d%d%d",&n,&A,&q); string ss;cin>>ss; for(int i=0;i<n;i++) if(ss[i]=='1') tot++; double correct=1.0*A/100.0*tot/n + (1.0-A)/100.0*(n-tot)/n; double wrong=1.0-correct; double ans=0.0; for(int i=0;i<=n-q;i++){ double res=1.0*C(n,i); res*=double_pow(wrong,i)*double_pow(correct,n-i); ans+=res; } printf("%.3f ",ans); return 0; }
附正解
/* 递推 F[i][j]:前i道题对j道的概率 考虑每道题做对与做错对f的贡献 */ #include<iostream> #include<cstring> #include<cstdio> using namespace std; int n,q; double f[55][55]; double a; int main(){ scanf("%d%lf%d",&n,&a,&q);a/=100.0; if(!q){ printf("1.000 "); return 0; } string ss;cin>>ss; f[0][0]=1.0; for(int i=1;i<=n;i++){ if(ss[i-1]=='1') f[i][0]=f[i-1][0]*(1.0-a); else f[i][0]=f[i-1][0]*a; for(int j=1;j<=i;j++){ if(ss[i-1]=='1') f[i][j]=f[i-1][j]*(1.0-a)+f[i-1][j-1]*a; else f[i][j]=f[i-1][j]*a+f[i-1][j-1]*(1.0-a); } } double ans=0.0; for(int i=n;i>=q;i--) ans+=f[n][i]; printf("%.3f ",ans); return 0; }