Codeforces Round #406 (Div. 1) A. Berzerk(博弈论)

本文探讨了在给定的状态转移规则中,如何通过win矩阵和cnt数组判断从某个状态v出发,是否能转移至必胜态或必败态,同时涉及循环状态的检测。通过dfs递归算法,展示了如何在有限的状态空间中进行遍历和决策。
摘要由CSDN通过智能技术生成

能转移到必败态的状态就是必胜态,只能转移到必胜态的状态就是必败态。反过来看,假设win[0][1]=win[1][1]=0,若当前为v,位置为now:(1)若win[v][now]=0,则win[v^1] [now-s[v^1][x]]=1 (2)若win[v][now]=1,则需要记录cnt[v^1] [now-s[v^1][x]] 是否等于k[v^1],也就是说要判断是否满足第二个条件
判断是否loop,若vis[v][now]==0,则loop

#include <iostream>  
#include <stdio.h>  
#include <string.h>   
#include <stack>  
#include <queue>   
#include <map>  
#include <set>  
#include <vector>  
#include <math.h>  
#include <bitset>  
#include <algorithm>  
#include <climits>
using namespace std;
#define ll long long 
// #define int long long 
const int N=1e6+10;
int n,k[2],dp[2][N],s[2][N],cnt[2][N];
int win[2][N],vis[2][N];
void dfs(int v,int now){
    int u=v^1;
    if(vis[v][now]) return ;
    vis[v][now]=1;
    for(int i=1;i<=k[u];i++){
        int to=(now-s[u][i]+n-1)%n+1;
        if(to==1) continue;
        if(win[v][now]==0){
            win[u][to]=1;
            dfs(u,to);
        }else if(++cnt[u][to]==k[u]){
            win[u][to]=0;
            dfs(u,to);
        }
    }
}
int main(){
    scanf("%d",&n);
    for(int i=0;i<2;i++){scanf("%d",&k[i]);for(int j=1;j<=k[i];j++) scanf("%d",&s[i][j]);}
    dfs(0,1);dfs(1,1);
    for(int i=0;i<2;i++){
        for(int j=2;j<=n;j++){
            cout<<(vis[i][j]?win[i][j]?"Win":"Lose":"Loop")<<" ";
        }cout<<endl;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值