Codeforces Round #459 (Div. 1) B. MADMAX

算法分析

博弈论sg函数 + 记忆化搜索

dp[u][v][w] 表示为 先手在 u 点 后手在 v 点 上一次操作的权值为 w 时,先手的胜负状况

考虑sg函数必胜必败态转移

sg的状态转移其实像是图上的dp转移

dp[u][v][w] 会转移到哪里呢,当前的先手为 u 后手为 v ,限制条件为  w

那么轮到 v 的这一轮时 先手就是 v ,后世就是 u 再往后任意走一个位置(我在这里假设成 e

并且到这个位置的权值要大于 w 

那么就是转移到看 dp[v][e.first][e.seocnd] 上,因为上一步是 u 走的一步权值为 e.second 的一步

那么记忆化搜索的过程就出来了

bool dfs(int u,int v,int w)
{
    if(vis[u][v][w]) return dp[u][v][w];
    vis[u][v][w] = 1;
    for(auto e : g[u])
    {
        if(e.second < w) continue;//不符合条件
        if(!dfs(v,e.first,e.second)) return dp[u][v][w] = true;
    }
    return dp[u][v][w] = false;
}

AC Code

#include<bits/stdc++.h>
using namespace std;
const int N = 110;

int dp[N][N][28],vis[N][N][28];
vector<pair<int,int>> g[N];

bool dfs(int u,int v,int w)//记忆化搜索
{
    if(vis[u][v][w]) return dp[u][v][w];//访问过 直接返回
    vis[u][v][w] = 1;//标记已经访问
    for(auto e : g[u])//转移下一个状态
    {
        if(e.second < w) continue;
        if(!dfs(v,e.first,e.second)) return dp[u][v][w] = true;
        //如果轮到 v 这一轮走的时候 走不了了 那么 u 就赢了
    }
    return dp[u][v][w] = false;//否则就输了
}
int main()
{

    int n,m;
    cin >> n >> m;
    for(int i = 1;i <= m;i ++)
    {
        int u,v;char c;
        cin >> u >> v >> c;
        g[u].push_back({v,c - 'a'});
    }
    for(int i = 1;i <= n;i ++)
    {
        for(int j = 1;j <= n;j ++)
        cout << (dfs(i,j,0) == true ? "A" : "B");
        cout <<"\n";
    }

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cold啦啦啦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值