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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章