Codeforces Round #406 (Div. 2) C 有向图博弈,dp

C. Berzerk

题意:n个星球围成一个圏,第一个星球是黑洞,有一个怪物在第2~n个星球上的任意一个。两个人分别有两个数集S1、S2,两人轮流从数集中选一个数 m,让怪物走 m 步。走到第一个星球则败,问怪物在第2~n个星球上时,先手胜负。

tags: 跑bfs,倒着来推。 (1)初始时,假设现在走到了第一个星球,为必败态,则往前推一步可以直接确定为必胜态。  (2)然后可以继续递推下去。如为必败,则上一步为必胜;如为必胜,则上一步可能为胜的概率就 -1,这里概率可以用个数组存好,初始为k[i],当上一步概率减至0时即为必败。 (3)最后没有遍历到的状态就是无限循环。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a;i<=b;i++)
#define per(i,b,a) for (int i=b;i>=a;i--)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define PII pair<int ,int >
#define MP make_pair
typedef long long ll;
const int N = 7005;

int k[3], a[3][N], dp[3][N], wn[3][N];    // dp[j][i]表示第j个人先手且怪物在第i+1点的胜负,wn[j][i]表示此状态可能胜的数量 
PII q[N<<2];
int n, top;
int main()
{
    scanf("%d", &n);
    scanf("%d", &k[0]); rep(i,1,k[0]) scanf("%d", &a[0][i]);
    scanf("%d", &k[1]); rep(i,1,k[1]) scanf("%d", &a[1][i]);
    rep(i,0,n-1) wn[0][i]=k[0], wn[1][i]=k[1];
    mes(dp, -1);
    dp[0][0]=dp[1][0]=0;         //怪物在第一个点为必败态
    q[0]=MP(0,0); q[1]=MP(1,0);
    top=1;
    rep(i,0,top) {
        int u=q[i].first, v=q[i].second;
        if(dp[u][v]==0) {    //必败状态 
            rep(j,1,k[u^1]) {
                int uu=u^1, vv=(v+n-a[uu][j])%n;    
                if(dp[uu][vv]==-1) {    //把能转移到必败状态的状态直接标为必胜状态,并加入队列 
                    dp[uu][vv]=1;
                    q[++top]=MP(uu,vv);
                }
            }
        } else {    //必胜状态
            rep(j,1,k[u^1]) {
                int uu=u^1, vv=(v+n-a[uu][j])%n;
                --wn[uu][vv];        //把能转移到必胜状态的状态的出度 -1,当它的出度为0且它没有遍历过时,就可以把它标为必败状态,并加入队列 
                if(dp[uu][vv]==-1 && wn[uu][vv]==0) {
                    dp[uu][vv]=0;
                    q[++top]=MP(uu,vv);
                }
            }
        }
    }
    
    rep(i,0,1) {
        rep(j,1,n-1) {
            if(dp[i][j]==-1) printf("Loop ");    //没有遍历到的点即为无限循环 
            else if(dp[i][j]==0) printf("Lose ");
            else printf("Win ");
        }
        puts("");
    } 

    return 0;
}
posted @ 2017-03-26 00:44  v9fly  阅读(242)  评论(0编辑  收藏  举报