区域赛前把所有dp类型练一遍(挖坑

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;
}

 

点赞