CCPC吉林D题,概率DP。暴力打表为2^n不可行,考虑每个点由什么状态转移过来。
设DP[i][j]表示到坚持到玩了i回合,赢了j次仍然没有结束的概率。
显然DP[i][j]=p1*DP[i-1][j]+p2*DP[i-1][j-1];//由上一场赢或者输转移过来。p1,p2表示分别的概率
然后赢的概率就从dp[i][j]下次必赢进行累加就是结果了。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
const double eps=1e-6;
double dp[1000][800];
double count1(double x,double y){
double res;
res=(y+1)*0.02+(x-y)*0.015;
if(res>=1.0)
res=1;
return res;
}
int main(){
int i,j,k,f1,f2,f3,f4,t1,t2,t3,t4;
//freopen("in.txt","r",stdin);
//freopen("out1.txt","w",stdout);
int n,m;
double p,q;
int T;
cin >> T;
while(T--){
memset(dp,0,sizeof(dp));
cin >> p;
q=0.02;
p/=100.0;
dp[1][1]=p*(1-q);
dp[1][0]=(1-p);
for(i=2;i<=500;i++){
for(j=0;j<=i;j++){
dp[i][j]+=p*(1-count1(i-1,j-1))*dp[i-1][j-1]+(1-p)*dp[i-1][j];
}
}
double res=0;
for(i=1;i<=500;i++)
for(j=0;j<=i;j++){
res+=(i+1.0)*p*(count1(i,j)*dp[i][j]);
}
printf("%.10lf\n",res+0.02*p);
}
return 0;
}