题意:在给定的一个有向无环图上,两个人分别从一个点出发,两人轮流从当前点沿某条边移动,要求经过的边的权值不小于上一轮对方经过的权值直到某一方不能移动。求一个n*n的胜负表
可能是我没学过组合游戏的关系?当时dfs不知道怎么转移
题解:
dp[x][y][c],表示先手在x,后手在y,上一次经过边权为c的胜负状态(1胜0负),此时从x往后走,假设从x->u,边权为v,要求v>=c,那么下一个状态就是dp[y][u][v]。
如果dp[y][u][v]该状态是0,则表示这是个先手必败态,那么就dp[x][y][c]是A先手胜
如果dp[y][u][v]该状态为1,就是一个先手必胜态,我们走与x相连的其他边,直到找到一个0状态。
我觉得可能学过组合游戏以后可能这题就很轻松?emmm
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#define LL long long
#define INF 0x3f3f3f3f
#define MOD 998244353
const int maxn = 1e5 + 5;
using namespace std;
int dp[105][105][30];
struct node{
int to;
int c;
node(){}
node(int too, int cc):to(too),c(cc){}
};
vector <node> vec[maxn];
bool dfs(int x, int y, int c){
if(dp[x][y][c] != -1)
return dp[x][y][c];
dp[x][y][c] = 0;
for(int i=0; i<vec[x].size(); i++){
node temp = vec[x][i];
if(temp.c >= c){
if(!dfs(y,temp.to,temp.c)){
dp[x][y][c] = 1;
break;
}
}
}
return dp[x][y][c];
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
memset(dp,-1,sizeof(dp));
for(int i=1; i<=m; i++){
int u,v;
char c;
scanf("%d%d %c",&u,&v,&c);
vec[u].push_back(node(v,(c-'a')));
}
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++)
if(dfs(i,j,0)) printf("A");
else printf("B");
printf("\n");
}
}