zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    SQLServer之删除索引
    SQLServer之修改索引
    SQLServer之创建辅助XML索引
    SQLServer之创建主XML索引
    SQLServer之创建全文索引
    SQLServer之创建唯一非聚集索引
    SQLServer之创建唯一聚集索引
    SQLServer之创建非聚集索引
    SQLServer之添加聚集索引
    给NSMutableArray添加copy属性就变成了NSArray
  • 原文地址:https://www.cnblogs.com/sbfhy/p/6617662.html
Copyright © 2011-2022 走看看