Codeforces 918D/917B - MADMAX

传送门:http://codeforces.com/contest/918/problem/D

本题是一个组合游戏问题——DAG上的动态规划问题。

有一张有向无环图(DAG)。有两个玩家在这张图上进行一个游戏:初始时,玩家A、B各占据一个结点,之后轮流沿着有向边移动;移动时的边权是不下降的。无法移动者输。

请打印一个n×n矩阵,这个矩阵的元代表获胜方(A/B),其ij列元的含义如下:玩家A的初始位置为结点i,玩家B的初始位置为结点j

对于DAG上的组合游戏,可以考虑DP。

定义布尔变量dp(u,v,c),代表当先手的初始位置为结点u,后手的初始位置为结点v,且上一次移动的边权为c时,先手是否能移动。则:

若存在有向边<u,x>,使得c≤cost<u,x>,且dp(v,x,cost<u,x>)=0,于是,一旦先手到达结点x后,后手将无法移动:于是先手必胜,即dp(u,v,c)=1;否则先手必败,即dp(u,v,c)=0。

参考程序如下:

#include <stdio.h>
#include <string.h>
#define MAX_N 101
#define MAX_C 26

int n, m;
int adj[MAX_N][MAX_N];
int dp[MAX_N][MAX_N][MAX_C];

int dfs(int u, int v, int c)
{
    if (dp[u][v][c] != -1) return dp[u][v][c];
    for (int x = 1; x <= n; x++) {
        if (adj[u][x] >= c && !dfs(v, x, adj[u][x]))
            return dp[u][v][c] = 1;
    }
    return dp[u][v][c] = 0;
}

int main(void)
{
    scanf("%d%d", &n, &m);
    memset(adj, -1, sizeof(adj));
    memset(dp, -1, sizeof(dp));
    while (m--) {
        int u, v;
        char ch;
        scanf("%d%d %c", &u, &v, &ch);
        adj[u][v] = ch - 'a';
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (dfs(i, j, 0)) putchar('A');
            else putchar('B');
        }
        putchar('\n');
    }
    return 0;
}

 

posted on 2018-02-01 21:59  SiuGinHung  阅读(259)  评论(0编辑  收藏  举报

导航