HDU 6224 (ICPC 沈阳 2017 H) Legends of the Three Kingdoms(记忆化搜索)

Legends of the Three Kingdoms

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 928    Accepted Submission(s): 148


 

Problem Description
In the game of Three Kingdoms’ Legends, there are 4 players called the Monarch, the Minister, the Rebel and theTraitor. They have h1,h2,h3,andh4 health points at the beginning. The players with positive health points aresurviving; the players with zero health points are dead.
The players take turns to move in each round of the game: the Monarch moves first, then the Rebel, the Minister,and finally the Traitor. In a player’s turn, if he/she is surviving, he/she must attack a player and the health points of that player will decrease by 1. Note that the dead players cannot attack the other players, and self attacking isnot allowed.
When one of the following events happens, the game ends immediately.
∙ Both of the Rebel and the Traitor are dead: The Monarch and the Minister win the game, no matter theminister is surviving or not.
∙ The Monarch is dead: If the Traitor is surviving and all the other players are dead, the Traitor wins; otherwisethe Rebel wins, no matter he/she is surviving or not.
The players have the following common knowledge on their strategies.
∙ The Monarch and the Minister never attack with each other.
∙ After attacking the chosen player, the probability of winning the game is maximized.
∙ If there are multiple players to choose, such that the winning probability is the same and maximized, all theseplayers will be chosen by equal chance.
Your task is to calculate the winning probability of each player.
 

 

Input
The first line is the number of test cases up to 10000. For each test case, there is a line containing 4 integers h1,h2,h3andh4 (0 < h1 < 40, 0 ≤ h2 < 40, 0 ≤ h3 < 40, 0 ≤ h4 < 40).
 

 

Output
For each test case, output a line of 3 winning probabilities with the precision of 6 digits, in which the first one is the Monarch and the Minister’s winning probability, the second one is the Rebel’s and the last one is the Traitor’s.
 

 

Sample Input
 
4 1 1 1 1 1 0 1 1 1 1 1 2 2 1 2 6
 

 

Sample Output
 
1.000000 0.000000 0.000000 0.000000 0.500000 0.500000 0.500000 0.500000 0.000000 0.250000 0.500000 0.250000
 

 

Source

题意:

给你四个人a,c,b,d的初始血量h1,h2,h3,h4(<40)

a,b,c,d(注意和输入不一样)四个人轮流操作,每个人可以任意选择一个人并砍他一下(使他血量-1)。

胜负规则如下:(据说是三国杀,然而我并木有玩过)

1、如果b和d血量为0,则a,c胜利(他俩是一伙的)

2、如果a血量为0时,bc血量都为0,则d胜利

3、如果a血量为0时,bc血量不都为0,则b胜利

4、a和c不会相互攻击

5、每个人都足够聪明,当轮到某个人攻击时,他会选择攻击那个使自己获胜概率最大的人x,如果有多个人相同,那么他等可能的攻击这些人。

问你最后ac、b、d获胜的概率。

思路:

直接记忆化搜索!!!

dp[i][a][b][c][d][x]表示i获胜、四个人血量分别为abcd、下一步该x操作的最大概率。

依次枚举攻击每个人,取一个最大的获胜概率,记录最大的获胜概率相同的总数,讨论每种情况。

注意,vis数组要全局初始化。

代码:

//#include<bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<queue>
#include<vector>
#include<map>
#define ll long long
#define inf 0x3f3f3f3f
#define mst(head,x,n) memset(head+1,x,n*sizeof(head[0]))
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
using namespace std;
const int maxn=4e2+5;
//const double pi=acos(-1.0);
const double eps=1e-13;
//const ll mo=1e9+7;
double dp[3][40][40][40][40][4];
bool vis[40][40][40][40][4];
int a[5];
template <typename T>
inline void read(T &X)
{
    X=0;int w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    if(w) X=-X;
}
void dfs(int a,int b,int c,int d,int x){
    if(vis[a][b][c][d][x]) return ;
    vis[a][b][c][d][x]=1;

    if(!b&&!d){
        dp[0][a][b][c][d][x]=1.0;
        dp[1][a][b][c][d][x]=0.0;
        dp[2][a][b][c][d][x]=0.0;
        return ;
    }

    if(!a){
        if(!b&&!c){
            dp[2][a][b][c][d][x]=1.0;
            dp[0][a][b][c][d][x]=0.0;
            dp[1][a][b][c][d][x]=0.0;
        }
        else {
            dp[1][a][b][c][d][x]=1.0;
            dp[0][a][b][c][d][x]=0.0;
            dp[2][a][b][c][d][x]=0.0;
        }
        return ;
    }

    if(x==0&&a==0||x==1&&b==0||x==2&&c==0||x==3&&d==0){
        dfs(a,b,c,d,(x+1)%4);
        rep(j,0,2)
        dp[j][a][b][c][d][x]=dp[j][a][b][c][d][(x+1)%4];
        return ;
    }
    int xx=0;
    int e=(x+1)%4;
    double d1=0.0;
    double d2=0.0;
    double d3=0;
    if(x==0||x==2){
        double t=-1.0;
        if(b>0) {
            dfs(a,b-1,c,d,e);
            double tmp=dp[0][a][b-1][c][d][e];
            if(tmp-t>eps){
                xx=1;
                t=tmp;
                d1=dp[0][a][b-1][c][d][e];
                d2=dp[1][a][b-1][c][d][e];
                d3=dp[2][a][b-1][c][d][e];
            }
            else if(fabs(tmp-t)<eps){
                xx++;
                d1+=dp[0][a][b-1][c][d][e];
                d2+=dp[1][a][b-1][c][d][e];
                d3+=dp[2][a][b-1][c][d][e];
            }
        }

        if(d>0) {
            dfs(a,b,c,d-1,e);
            double tmp=dp[0][a][b][c][d-1][e];
            if(tmp-t>eps){
                xx=1;
                t=tmp;
                d1=dp[0][a][b][c][d-1][e];
                d2=dp[1][a][b][c][d-1][e];
                d3=dp[2][a][b][c][d-1][e];
            }
            else if(fabs(tmp-t)<eps){
                xx++;
                d1+=dp[0][a][b][c][d-1][e];
                d2+=dp[1][a][b][c][d-1][e];
                d3+=dp[2][a][b][c][d-1][e];
            }
        }
        }
        if(x==1){
            double t=-1.0;
            if(a>0) {
                dfs(a-1,b,c,d,e);
                double tmp=dp[1][a-1][b][c][d][e];
                if(tmp-t>eps){
                    xx=1;
                    t=tmp;
                    d1=dp[0][a-1][b][c][d][e];
                    d2=dp[1][a-1][b][c][d][e];
                    d3=dp[2][a-1][b][c][d][e];
                }
                else if(fabs(tmp-t)<eps){
                    xx++;
                    d1+=dp[0][a-1][b][c][d][e];
                    d2+=dp[1][a-1][b][c][d][e];
                    d3+=dp[2][a-1][b][c][d][e];
                }
            }
            if(c>0) {
                dfs(a,b,c-1,d,e);
                double tmp=dp[1][a][b][c-1][d][e];
                if(tmp-t>eps){
                    xx=1;
                    t=tmp;
                    d1=dp[0][a][b][c-1][d][e];
                    d2=dp[1][a][b][c-1][d][e];
                    d3=dp[2][a][b][c-1][d][e];
                }
                else if(fabs(tmp-t)<eps){
                    xx++;
                    d1+=dp[0][a][b][c-1][d][e];
                    d2+=dp[1][a][b][c-1][d][e];
                    d3+=dp[2][a][b][c-1][d][e];
                }
            }

            if(d>0) {
                dfs(a,b,c,d-1,e);
                double tmp=dp[1][a][b][c][d-1][e];
                if(tmp-t>eps){
                    xx=1;
                    t=tmp;
                    d1=dp[0][a][b][c][d-1][e];
                    d2=dp[1][a][b][c][d-1][e];
                    d3=dp[2][a][b][c][d-1][e];
                }
                else if(fabs(tmp-t)<eps){
                    xx++;
                    d1+=dp[0][a][b][c][d-1][e];
                    d2+=dp[1][a][b][c][d-1][e];
                    d3+=dp[2][a][b][c][d-1][e];
                }
            }
        }
        if(x==3){
            double t=-1.0;
            if(a>0) {
                dfs(a-1,b,c,d,e);
                double tmp=dp[2][a-1][b][c][d][e];
                if(tmp-t>eps){
                    xx=1;
                    t=tmp;
                    d1=dp[0][a-1][b][c][d][e];
                    d2=dp[1][a-1][b][c][d][e];
                    d3=dp[2][a-1][b][c][d][e];
                }
                else if(fabs(tmp-t)<eps){
                    xx++;
                    d1+=dp[0][a-1][b][c][d][e];
                    d2+=dp[1][a-1][b][c][d][e];
                    d3+=dp[2][a-1][b][c][d][e];
                }
            }
            if(c>0) {
                dfs(a,b,c-1,d,e);
                double tmp=dp[2][a][b][c-1][d][e];
                if(tmp-t>eps){
                    xx=1;
                    t=tmp;
                    d1=dp[0][a][b][c-1][d][e];
                    d2=dp[1][a][b][c-1][d][e];
                    d3=dp[2][a][b][c-1][d][e];
                }
                else if(fabs(tmp-t)<eps){
                    xx++;
                    d1+=dp[0][a][b][c-1][d][e];
                    d2+=dp[1][a][b][c-1][d][e];
                    d3+=dp[2][a][b][c-1][d][e];
                }
            }

            if(b>0) {
                dfs(a,b-1,c,d,e);
                double tmp=dp[2][a][b-1][c][d][e];
                if(tmp-t>eps){
                    xx=1;
                    t=tmp;
                    d1=dp[0][a][b-1][c][d][e];
                    d2=dp[1][a][b-1][c][d][e];
                    d3=dp[2][a][b-1][c][d][e];
                }
                else if(fabs(tmp-t)<eps){
                    xx++;
                    d1+=dp[0][a][b-1][c][d][e];
                    d2+=dp[1][a][b-1][c][d][e];
                    d3+=dp[2][a][b-1][c][d][e];
                }
            }
        }
        dp[0][a][b][c][d][x]=d1/xx;
        dp[1][a][b][c][d][x]=d2/xx;
        dp[2][a][b][c][d][x]=d3/xx;
}
int main(){
    int T,cas=1;
    mst(a,0,4);
    read(T);
    while(T--){
        rep(i,1,4) read(a[i]);
        swap(a[2],a[3]);
        dfs(a[1],a[2],a[3],a[4],0);
        printf("%.6lf %.6lf %.6lf\n",dp[0][a[1]][a[2]][a[3]][a[4]][0],dp[1][a[1]][a[2]][a[3]][a[4]][0],dp[2][a[1]][a[2]][a[3]][a[4]][0]);
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值