codeforce 459 DIV2 D题
题意
在一个DAG上面有N个点M条边,每一条边上都有一个小写字母。两个人Max and Lucas 每个人一颗棋子,两个人轮流行棋,当前这一步选择的路上面的字母必须大于等于上一步路上面的字母,当轮到一个人她无法行棋时她便输了。每个人行棋时走会走最优情况。输出所有两个人初始位置的输赢情况。
分析
记忆搜索;dp[u][v][c]当前先手在点u,后手在点v,能走的字母大于等于c;先手胜利则dp[u][v][c]=1否则dp[u][v][c]=0;
若G[u][x]=c2,且c2>=c,则if(dp[v][x][c2]==0),dp[u][v][c]=1;
其实很好理解当前先手在u,后手在v,下一步先手走到x时,那么先手变后手,后手变前手。
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <iostream> 5 using namespace std; 6 const int maxn=100+10; 7 int n,m; 8 char G[maxn][maxn]; 9 int dp[maxn][maxn][28]; 10 int dfs(int u,int v,char c){ 11 if(dp[u][v][c-'a']!=-1) 12 return dp[u][v][c-'a']; 13 for(int i=1;i<=n;i++){ 14 if(G[u][i]>=c) 15 if(dfs(v,i,G[u][i])==0)return dp[u][v][c-'a']=1; 16 } 17 return dp[u][v][c-'a']=0; 18 } 19 int main(){ 20 memset(G,0,sizeof(G)); 21 memset(dp,-1,sizeof(dp)); 22 scanf("%d%d",&n,&m); 23 int a,b,c; 24 for(int i=1;i<=m;i++){ 25 scanf("%d%d %c",&a,&b,&c); 26 G[a][b]=c; 27 } 28 for(int i=1;i<=n;i++){ 29 for(int j=1;j<=n;j++){ 30 dfs(i,j,'a'); 31 } 32 } 33 for(int i=1;i<=n;i++){ 34 if(i!=1)cout<<""<<endl; 35 for(int j=1;j<=n;j++){ 36 if(dp[i][j][0]) 37 cout<<"A"; 38 else 39 cout<<"B"; 40 } 41 } 42 return 0; 43 }