BZOJ4832: [Lydsy1704月赛]抵制克苏恩 (记忆化搜索 + 概率DP)

题意:模拟克苏恩打奴隶战对对方英雄所造成的伤害

题解:因为昨(今)天才写过记忆化搜索 所以这个就是送经验了

   1A还冲了个榜 但是我惊奇的发现我数组明明就比数据范围开小了啊???

 

#include <bits/stdc++.h>
using namespace std;

int k, a, b, c;
double dp[50][8][8][8];

double dfs(int at, int x, int y, int z)
{
    if(dp[at][x][y][z]) return dp[at][x][y][z];

    double tmp = 0;
    double fm = 1.0 * (x + y + z + 1.0);
    tmp += 1.0 / fm * (dfs(at - 1, x, y, z) + 1.0);
    if(x) tmp += 1.0 * x / fm * dfs(at - 1, x - 1, y, z);
    if(y)
    {
        if(x + y + z == 7) tmp += 1.0 * y / fm * dfs(at - 1, x + 1, y - 1, z);
        else tmp += 1.0 * y / fm * dfs(at - 1, x + 1, y - 1, z + 1);
    }
    if(z)
    {
        if(x + y + z == 7) tmp += 1.0 * z / fm * dfs(at - 1, x, y + 1, z - 1);
        else tmp += 1.0 * z / fm * dfs(at - 1, x, y + 1, z);
    }
    dp[at][x][y][z] = tmp;
    return tmp;
}

int main()
{
    int T;
    scanf("%d", &T);
    for(int i = 0; i < 8; i++)
        for(int j = 0; j < 8; j++)
        {
            if(i + j > 7) continue;
            for(int k = 0; k < 8; k++)
            {
                if(i + j + k > 7) continue;
                dp[1][i][j][k] = 1.0 / (i + j + k + 1.0);
            }
        }

    while(T--)
    {
        scanf("%d%d%d%d", &k, &a, &b, &c);
        double ans = dfs(k, a, b, c);
        printf("%.2lf\n", ans);
    }
    return 0;
}
View Code

 

posted @ 2018-10-12 11:17  lwqq3  阅读(200)  评论(0编辑  收藏  举报