UESTC 1654 肆虐的病毒 博弈DP

来源:互联网 发布:淘宝成人杂志 编辑:程序博客网 时间:2024/04/29 13:28

题目链接:http://acm.uestc.edu.cn/#/problem/show/1654

PS:这道题实际上是CF上的这道题http://codeforces.com/contest/786/problem/A

解法:博弈DP。要知道一些博弈DP的转移点。

对于必胜态,后继必然有一个必败态

对于必败态,后继必然全部是必胜态

这里写图片描述

#include <bits/stdc++.h>using namespace std;const int maxn = 7e3+7;int dp[2][maxn];//dp[i][j]代表第i个人在第j个位置的状态//必胜态1//必败态0//平局就是没被访问到的点//对于必胜态,后继必然有一个必败态//对于必败态,后继必然全部是必胜态int deg[2][maxn];int n;vector <int> g[2];int dfs(int k, int i, int v){    int &ret = dp[k][i];    if(~ret) return ret;    ret = v;    if(v == 0){        for(int x : g[k^1]){            int j = (i + n - x) % n;            if(j == 0) continue;            dfs(k^1, j, 1);        }    }    else{        for(int x : g[k^1]){            int j = (i + n - x) % n;            if(j == 0) continue;            if(--deg[k^1][j] == 0) dfs(k^1, j, 0);        }    }    return ret;}int main(){    while(scanf("%d", &n) != EOF)    {        for(int k = 0; k < 2; k++){            int x;            cin >> x;            g[k].clear();            g[k].reserve(x);            while(x--){                int y;                cin >> y;                g[k].push_back(y);            }            for(int i = 1; i < n; i++) deg[k][i] = g[k].size();        }        memset(dp, -1, sizeof(dp));        dfs(0, 0, 0);        dfs(1, 0, 0);        string s[3] = {"Loop", "Lose", "Win"};        for(int k = 0; k < 2; k++){            for(int i = 1; i < n; i++){                if(dp[k][i] == 0) printf("Lose ");                else if(dp[k][i] == 1) printf("Win ");                else printf("Loop ");            }            printf("\n");        }    }    return 0;}
原创粉丝点击