The Moon HDU6558(期望/概率dp/记忆化dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6558

题意很好理解,造着他意思记忆化dp下就好。
s o l v e ( p , q ) = p q + p ( 1 q ) ( s o l v e ( p , q + 2 solve(p,q)=p*q+p*(1-q)*(solve(p,q+2%)+1)+(1-p)*solve(p,q+1.5%)
一开始忘了初始条件,当q==100%时,期望等于1/p。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=110;

double dp[maxn][2];//dp[x][y] q=x+y/2
double p;
double solve(int x,int y){
    if(dp[x][y]>=0.0) return dp[x][y];
    if(x*2+y==200) return 1.0/p;//递归结束条件
    double &res=dp[x][y];
    double q=(1.0*x+1.0*y/2)/100;
    res=p*q;
    if(2*x+y<200){
        if(x+2>=100)
            res+=p*(1-q)*(solve(100,0)+1.0);
        else
            res+=p*(1-q)*(solve(x+2,y)+1.0);
    }
    x+=1;y+=1;
    if(y>=2){
        x+=1;y-=2;
    }
    if(2*x+y>=200){//
        x=100;y=0;
    }
    res+=(1-p)*(solve(x,y)+1.0);
    return res;
}
void test(){
    for(int a=1;a<=100;a++){
        p=1.0*a/100;
        solve(100,0);
        for(int i=0;i<=100;i++)
            for(int j=0;j<=1;j++)
                dp[i][j]=-1;
        for(int i=99;i>=2;i--){
            for(int j=1;j>=0;j--){
                solve(i,j);
            }
        }
        printf("p: %d/100: %.10f\n",a,dp[2][0]);
    }
}
int main(){
    //test();
    int t;scanf("%d",&t);
    int cas=1;
    while(t--){
        int a;
        scanf("%d",&a);
        p=1.0*a/100;
        solve(100,0);
        for(int i=0;i<=100;i++)
            for(int j=0;j<=1;j++)
                dp[i][j]=-1;
        for(int i=99;i>=2;i--){
            for(int j=1;j>=0;j--){
                solve(i,j);
            }
        }
        printf("Case %d: %.10f\n",cas++,dp[2][0]);
    }
}
发布了71 篇原创文章 · 获赞 1 · 访问量 2834

猜你喜欢

转载自blog.csdn.net/weixin_43918473/article/details/102983737