Hdu 6224 博弈爆搜

题意大概是三国杀,主忠反内顺序行动,给初始血量,每个人轮到他时必须选择打别人一滴血(主忠不能互打),每个人都选择自己获胜概率最高的方法,如果获胜概率相同随机选择一种方案。
由于血量不超过40,所有的状态是4*40*40*40*40,直接搜就行了。但是我一开始算错了空间,强行只记了主反获胜概率,内的概率用1-主-反,然后因为精度WA得生活不能自理,改了就AC了。
代码:

#include 
using namespace std;
const double eps=1e-13;
struct node {
    double a, b, c;
    void init(){
        a=b=c=-1;
    }
};
bool vis[4][40][40][40][40];
double a[4][40][40][40][40];
double b[4][40][40][40][40];
double c[4][40][40][40][40];
node dfs(int p, int x, int y, int z, int w){
    if(vis[p][x][y][z][w]){
        return (node){a[p][x][y][z][w], b[p][x][y][z][w], c[p][x][y][z][w]};
    }
    vis[p][x][y][z][w]=true;
    if(x==0&&y==0&&z==0&&w>0){
        a[p][x][y][z][w]=0;
        b[p][x][y][z][w]=0;
        c[p][x][y][z][w]=1;
    }
    else if(x==0){
        a[p][x][y][z][w]=0;
        b[p][x][y][z][w]=1;
        c[p][x][y][z][w]=0;
    }
    else if(y==0&&w==0){
        a[p][x][y][z][w]=1;
        b[p][x][y][z][w]=0;
        c[p][x][y][z][w]=0;
    }
    else if(y==0&&p==1){
        node tmp=dfs((p+1)%4, x, y, z, w);
        a[p][x][y][z][w]=tmp.a;
        b[p][x][y][z][w]=tmp.b;
        c[p][x][y][z][w]=tmp.c;
    }
    else if(z==0&&p==2){
        node tmp=dfs((p+1)%4, x, y, z, w);
        a[p][x][y][z][w]=tmp.a;
        b[p][x][y][z][w]=tmp.b;
        c[p][x][y][z][w]=tmp.c;
    }
    else if(w==0&&p==3){
        node tmp=dfs((p+1)%4, x, y, z, w);
        a[p][x][y][z][w]=tmp.a;
        b[p][x][y][z][w]=tmp.b;
        c[p][x][y][z][w]=tmp.c;
    }
    else{
        //assert(y!=0||w!=0);
        if(p==0){
            node tmp[2];
            for(int i=0;i<2;i++)tmp[i].init();
            if(y>0){
                tmp[0]=dfs((p+1)%4, x, y-1, z, w);
            }
            if(w>0){
                tmp[1]=dfs((p+1)%4, x, y, z, w-1);
            }
            double am=-1;
            for(int i=0;i<2;i++){
                am=max(am, tmp[i].a);
            }
            double as=0, bs=0, cs=0;
            int cnt=0;
            for(int i=0;i<2;i++){
                if(am==tmp[i].a){
                    cnt++;
                    as+=tmp[i].a;
                    bs+=tmp[i].b;
                    cs+=tmp[i].c;
                }
            }
            as/=cnt;
            bs/=cnt;
            cs/=cnt;
            a[p][x][y][z][w]=as;
            b[p][x][y][z][w]=bs;
            c[p][x][y][z][w]=cs;
        }
        else if(p==1){
            node tmp[3];
            for(int i=0;i<3;i++)tmp[i].init();
            if(x>0){
                tmp[0]=dfs((p+1)%4, x-1, y, z, w);
            }
            if(z>0){
                tmp[1]=dfs((p+1)%4, x, y, z-1, w);
            }
            if(w>0){
                tmp[2]=dfs((p+1)%4, x, y, z, w-1);
            }
            double bm=-1;
            for(int i=0;i<3;i++){
                bm=max(bm, tmp[i].b);
            }
            double as=0, bs=0, cs=0;
            int cnt=0;
            for(int i=0;i<3;i++){
                if(bm==tmp[i].b){
                    cnt++;
                    as+=tmp[i].a;
                    bs+=tmp[i].b;
                    cs+=tmp[i].c;
                }
            }
            as/=cnt;
            bs/=cnt;
            cs/=cnt;
            a[p][x][y][z][w]=as;
            b[p][x][y][z][w]=bs;
            c[p][x][y][z][w]=cs;
        }
        else if(p==2){
            node tmp[2];
            for(int i=0;i<2;i++)tmp[i].init();
            if(y>0){
                tmp[0]=dfs((p+1)%4, x, y-1, z, w);
            }
            if(w>0){
                tmp[1]=dfs((p+1)%4, x, y, z, w-1);
            }
            double am=-1;
            for(int i=0;i<2;i++){
                am=max(am, tmp[i].a);
            }
            double as=0, bs=0, cs=0;
            int cnt=0;
            for(int i=0;i<2;i++){
                if(am==tmp[i].a){
                    cnt++;
                    as+=tmp[i].a;
                    bs+=tmp[i].b;
                    cs+=tmp[i].c;
                }
            }
            as/=cnt;
            bs/=cnt;
            cs/=cnt;
            a[p][x][y][z][w]=as;
            b[p][x][y][z][w]=bs;
            c[p][x][y][z][w]=cs;
        }
        else if(p==3){
            node tmp[3];
            for(int i=0;i<3;i++)tmp[i].init();
            if(x>0){
                tmp[0]=dfs((p+1)%4, x-1, y, z, w);
            }
            if(z>0){
                tmp[1]=dfs((p+1)%4, x, y, z-1, w);
            }
            if(y>0){
                tmp[2]=dfs((p+1)%4, x, y-1, z, w);
            }
            double cm=-1;
            for(int i=0;i<3;i++){
                cm=max(cm, tmp[i].c);
            }
            double as=0, bs=0, cs=0;
            int cnt=0;
            for(int i=0;i<3;i++){
                if(cm==tmp[i].c){
                    cnt++;
                    as+=tmp[i].a;
                    bs+=tmp[i].b;
                    cs+=tmp[i].c;
                }
            }
            as/=cnt;
            bs/=cnt;
            cs/=cnt;
            a[p][x][y][z][w]=as;
            b[p][x][y][z][w]=bs;
            c[p][x][y][z][w]=cs;
        }
    }
    return (node){a[p][x][y][z][w], b[p][x][y][z][w], c[p][x][y][z][w]};
}
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        int x, y, z, w;
        scanf("%d%d%d%d", &x, &z, &y, &w);
        node ans=dfs(0, x, y, z, w);
        printf("%.6f %.6f %.6f\n", ans.a, ans.b, ans.c);
    }
}

你可能感兴趣的:(博弈,暴力)