148D

概率dp+记忆化搜索

dp[i][j][0]表示当前公主走公主赢的概率,dp[i][j][1]表示当前龙走公主赢的概率,然后剩下的就是一些细节的讨论,记忆化搜索很方便

#include<bits/stdc++.h>
using namespace std;
const int N = 1005;
int n, m;
double dp[N][N][2];
double dfs(int n, int m, int f)
{
    if(f == 1 && n + m <= 2) return 0.0;
    if(n == 0) return 0.0;
    if(m == 0) return f ? 0.0 : 1.0;
    if(dp[n][m][f] >= 0.0) return dp[n][m][f];
    dp[n][m][f] = 0.0;
    if(f == 0) dp[n][m][f] = (double)n / (double)(n + m) + dfs(n, m - 1, f ^ 1) * (double)m / (double)(n + m);
    else 
    {
        double t = (double)n / (double)(n + m);
        if(m >= 2) dp[n][m][f] = (1.0 - t) * ((double)(m - 1) / (double)(n + m - 1) * dfs(n, m - 2, f ^ 1) + (double)n / (double)(n + m - 1) * dfs(n - 1, m - 1, f ^ 1));
        else dp[n][m][f] = (1.0 - t) * dfs(n - 1, m - 1, f ^ 1);
    }
    return dp[n][m][f];
}
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 0; i <= n; ++i)
        for(int j = 0; j <= m; ++j) dp[i][j][0] = dp[i][j][1] = -1.0; 
    printf("%.10f\n", dfs(n, m, 0));
    return 0;
}
View Code

 

posted @ 2017-10-23 22:46  19992147  阅读(142)  评论(0编辑  收藏  举报