题目链接

题意

给定一个 \(DAG\),每个边的权值为一个字母。两人初始各占据一个顶点(可以重合),轮流移动(沿着一条边从一个顶点移动到另一个顶点),要求每次边上的权值 \(\geq\) 上一次的权值。无法移动者输。

要求:对所有可能的初始情况,给出一张胜负表。

思路

特殊情况

  1. 两人在同一个顶点上,那么必然是先手输;

  2. 如果有\(u\rightarrow v\)边,并且先手在 \(u\) 上,后手在 \(v\) 上,且先手此时可以移动(判断边的权值),那么必然是先手赢

一般情况

考虑用 \(dp[u][v][w]\) 表示先手在 \(u\),后手在 \(v\),上一次移动的权值为 \(w\) 时,先手能否移动。

如果有 \(u\rightarrow x\) 可行(权值\(ww\geq w\)) 且 \(dp[v][x][ww]==false\),那么意味着先手只要走到 \(x\),后手就无路可走了。因此,先手有必胜策略;否则先手必败。

因为是 \(DAG\),所以可以用记忆化搜索。

联想

其实这里如果联想到 组合游戏 就很好理解了。

如果一个状态的所有后继都是先手必胜态(N),那么这个状态是先手必败态(P)。

如果一个状态能走到某一个先手必败态(P),那么这个状态就是先手必胜态(N)。

如果不考虑搜索复杂度的话,组合游戏其实也就是:在给定的DAG上确定状态是P态还是N态。而这道题恰好点数比较少,故真的就可以直接搜索了。

Code

#include <bits/stdc++.h>
#define maxn 110
#define maxm 5010
using namespace std;
typedef long long LL;
int mp[maxn][maxn];
int ne[maxn], tot;
struct Edge { int to, ne, w; }edge[maxm << 1];
bool vis[maxn][maxn][26], dp[maxn][maxn][26];
void add(int u, int v, int c) {
edge[tot] = {v, ne[u], c};
ne[u] = tot++;
}
int dfs(int u, int v, int ch) {
if (vis[u][v][ch]) return dp[u][v][ch];
vis[u][v][ch] = true;
if (u == v) return false;
if (mp[u][v]) {
if (ch <= mp[u][v]) return dp[u][v][ch] = true;
}
for (int i = ne[u]; ~i; i = edge[i].ne) {
int x = edge[i].to; char ww = edge[i].w;
if (ch <= ww && !dfs(v, x, ww)) return dp[u][v][ch] = true;
}
return false;
}
int main() {
memset(ne, -1, sizeof ne);
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < m; ++i) {
int u, v; char c;
scanf("%d%d %c", &u, &v, &c);
mp[u][v] = c-'a';
add(u, v, c-'a');
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
putchar(dfs(i, j, 0) ? 'A' : 'B');
}
puts("");
}
return 0;
}

Codeforces 918D MADMAX 图上dp 组合游戏的更多相关文章

  1. Codeforces 918D - MADMAX

    918D - MADMAX 思路: dp+记忆化搜索 状态:dp[i][j][w]表示先手在i节点,后手在j节点,这一轮的字母为w的结果,如果为true,则表示先手必赢,否则后手必赢. 状态转移:如果 ...

  2. zoj1232Adventure of Super Mario(图上dp)

    题目连接: 啊哈哈.点我点我 思路: 这个题目是一个图上dp问题.先floyd预处理出图上全部点的最短路,可是在floyd的时候,把可以用神器的地方预处理出来,也就是转折点地方不能为城堡..预处理完成 ...

  3. CodeForces 918D MADMAX(博弈+记忆化搜索)

    time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...

  4. Codeforces 225C Barcode(矩阵上DP)

    题目链接:http://codeforces.com/contest/225/problem/C 题目大意: 给出一个矩阵,只有两种字符'.'和'#',问最少修改多少个点才能让每一列的字符一致,且字符 ...

  5. 洛谷 P2656 (缩点 + DAG图上DP)

    ### 洛谷 P2656 题目链接 ### 题目大意: 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖 ...

  6. poj 3635 Full Tank? ( 图上dp )

    题意: 已知每一个点的加油站的油价单位价格(即点权).每条路的长度(边权). 有q个询问.每一个询问包含起点s.终点e和油箱容量. 问从起点走到终点的最小花费.假设不可达输出impossible,否则 ...

  7. [Luogu P3119] [USACO15JAN]草鉴定Grass Cownoisseur (缩点+图上DP)

    题面 传送门:https://www.luogu.org/problemnew/show/P3119 Solution 这题显然要先把缩点做了. 然后我们就可以考虑如何处理走反向边的问题. 像我这样的 ...

  8. Codeforces 918D/917B - MADMAX

    传送门:http://codeforces.com/contest/918/problem/D 本题是一个组合游戏问题——DAG上的动态规划问题. 有一张有向无环图(DAG).有两个玩家在这张图上进行 ...

  9. [正经分析] DAG上dp两种做法的区别——拓扑序与SPFA

    在下最近刷了几道DAG图上dp的题目. 要提到的第一道是NOIP原题<最优贸易>.这是一个缩点后带点权的DAG上dp,它同时规定了起点和终点. 第二道是洛谷上的NOI导刊题目<最长路 ...

随机推荐

  1. DeepFaceLab进阶(4):通过Colab免费使用Tesla K80 跑模型!

    当学会了换脸软件DeepFaceLab基本使用,各种参数配置,各有优化技能之后.唯一约束你的可能是电脑配置. CPU能跑,但是慢到怀疑人生,低配模型都得跑一周 低配显卡,显存不够,H128 根本就跑不 ...

  2. 【php】session_start 报 no such file

    如果是yum安装修改php-fpm.conf 里面的 session.save_path 如果是编译的,修改php.ini 的session.save_path (此条未测试)

  3. JavaScript事件对象与事件的委托

    事件对象 包含事件相关的信息,如鼠标.时间.触发的DOM对象等 js默认将事件对象封装好,并自动的以参数的形式,传递给事件处理函数的第1个参数,如下: document.getElementsByTa ...

  4. Essential C++ 3.1 节的代码练习——指针方式

    // // PointerToValue.cpp // Working // // Created by Hawkins, Dakota Y on 6/3/16. // Copyright 2016 ...

  5. CCPC 2016-2017, Finals

    A. HDU 5999 The Third Cup is Free 简单模拟. B. HDU 6000 Wash n 件衣服, m 个洗衣机,k 个烘干机.每个洗衣机和烘干机需要不同的时间.问 n 件 ...

  6. Android引导页过多导致OOM内存泄漏

    摘要:前几天推广我们APP的时候,有些手机加载引导页的时候会闪退或崩溃,在Bugly显示是OOM异常.    然后Bugly上面显示的解决方案是: 该异常表示未能成功分配字节内存,通常是因为内存不足导 ...

  7. 消息框模块-tkinter

    import tkinter.messagebox # 这个是消息框,对话框的关键from tkinter import * error_fp_list = [[973.45, '河北卡卡汽车贸易有限 ...

  8. Contest1893 - 2019年6月多校联训b层测试1

    传送门 密码:waxadyt T1 暴力 对于任意相邻的两个值 中间能到达的最大高度是固定的 加上头尾,判一下就好了 代码//感谢Th Au K #include<bits/stdc++.h&g ...

  9. SVM python小样例

    SVM有很多种实现,但是本章只关注其中最流行的一种实现,即序列最小化(SMO)算法在此之后,我们将介绍如何使用一种称为核函数的方式将SVM扩展到更多的数据集上基于最大间隔的分割数据优点:泛化错误率低, ...

  10. Tensorflow打造聊天机器人

    Tensorflow聊天机器人 聊天机器人也叫做对话系统,是一个热门领域.微软.facebook.苹果.google.微信.slack都在上面做了大的投入,这是一波新的试图改变人和服务交流的创业浪潮. ...