题目:
分析:
这道题主要就是数学问题,也考察了动态规划,用总概率1减去不能构成强数据的概率。
题目用到了组合数,表达本来应该长这样:
但是我打不出来,就只好用C(m,n)表示了。
组合数递推公式:C(M-1,N-1)+C(M-1,N)=C(M,N)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
int n,c[105][105];
double ans,p,f[105][105][105];
void pre(int x)
{
for(int i=1;i<=x;i++)c[i][1]=i;//C(n,1)=n
for(int i=2;i<=x;i++)
for(int j=2;j<=x;j++)
c[i][j]=c[i-1][j]+c[i-1][j-1];//递推式求所有需要的C(m,n)
}
double Pow(double x,int b)//快速幂
{
double res=1;
for(;b;b/=2,x*=x)
if(b&1)res*=x;
return res;
}
int main()
{
freopen("random.in","r",stdin);
freopen("random.out","w",stdout);
scanf("%d%lf",&n,&p);
p=p*1.0/1000;
pre(n);//把排列组合预处理
f[0][0][0]=1;
for(int i=0;i<=n;i++)
for(int j=0;j<=i/2;j++)
for(int k=0;k<=i/3;k++)
{
f[i+1][j][k]+=f[i][j][k]*Pow(1-p,i);
f[i+1][j+1][k]+=(i-2*j-3*k)*f[i][j][k]*Pow(1-p,i-1)*p;
f[i+1][j][k+1]+=c[i-2*j-3*k][2]*f[i][j][k]*Pow(1-p,i-2)*p*p;
f[i+1][j-1][k+1]+=2*j*f[i][j][k]*Pow(1-p,i-1)*p+j*f[i][j][k]*Pow(1-p,i-2)*p*p;//4、5合并到一起了
}
ans=1;
for(int j=0;j<=n/2;j++)
for(int k=0;k<=n/3;k++)
ans-=f[n][j][k];//用总概率减去不可行概率
printf("%0.4lf\n",ans);
return 0;
}
本题结。