MADMAX -每天一把CF - 20201116

2020-11-16

dp

918D 1700

题目

原题链接:https://codeforces.com/problemset/problem/918/D

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YhPY22vo-1605541910705)(918D.assets/image-20201116224341633.png)]

思路

题目大意:给定一个 DAG,每个边的权值为一个字母。两人初始各占据一个顶点(可以重合),轮流移动(沿着一条边从一个顶点移动到另一个顶点),要求每次边上的权值 ≥上一次的权值。无法移动者输。要求:对所有可能的初始情况,给出一张胜负表。

思路:

图上DP我真的一脸懵逼,2000+的题都没这恐怖,图涂

思路来自 https://www.cnblogs.com/kkkkahlua/p/8386936.html

思路我就不写了 涂

大佬强的

代码实现

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <string>
#include <queue>
using namespace std;

#define mes0(c) memset((c),0,sizeof(c))
#define mesi(c) memset((c),ifi,sizeof(c))
#define mes(c,n) memset((c),(n),sizeof(c))
#define fsios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define rep1(n) for (int i=1;i<=(n);i++)
#define rep2(n) for (int j=1;j<=(n);j++)
#define inp(a, n) for (int i = 1; i <= (n); i++) cin >> a[i];
#define ll long long
#define fi first
#define se second

const ll MAX = 200;
const int ifi = 0x3f3f3f3f;
const int mod = 1e9 + 7;


int n, m;
int mp[MAX][MAX];
int dp[MAX][MAX][30];
int vis[MAX][MAX][30];

bool dfs(int u, int v, int w) {
	if (vis[u][v][w]) return dp[u][v][w];//记忆化
	if (u == v) return dp[u][v][w] = false;//同起点先手必输
	if (mp[u][v] && w <= mp[u][v]) return dp[u][v][w] = true;//uv有路且可行则先手必赢

	vis[u][v][w] = 1;
	for (int i = 1; i <= n; i++) {
		if (mp[u][i] && w <= mp[u][i] && !dfs(v, i, mp[u][i]))
			return dp[u][v][w] = true;
	}
	return dp[u][v][w] = false;
}

int main() {
	fsios;

	while (cin >> n >> m) {
		int u, v; char c;
		mes0(mp); mes0(dp); mes0(vis);

		rep1(m) {
			cin >> u >> v >> c;
			mp[u][v] = c - 'a' + 1;
		}

		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				cout << (dfs(i, j, mp[i][j]) == false ? 'B' : 'A');
			}
			cout << endl;
		}

	}

	return 0;
}
相关推荐
©️2020 CSDN 皮肤主题: 黑客帝国 设计师:白松林 返回首页