【博弈论+记忆化dp+visit数组+回溯】acm 2014 西安赛区 H problem make you happy

来源:互联网 发布:每年车祸数据统计 编辑:程序博客网 时间:2024/05/01 04:58

代码如下,过了测试数据。

记忆化dp

注意visit[a][b][tag]记录是否之前到达了当前的状态,如果到达过,说明进入了一个环,回溯。

注意回溯的时候,不要设置res[a][b][tag],因为该结果可能尚未产生。


#include<vector>#include<iostream>#include<string.h>using namespace std;// -1: alice win,  1: bob win, -2: initedint res[100][100][2];//[a][b][if a go now]bool visit[100][100][2];// -1: alice win,  1: bob win// a_f: if alice go nowint dfs(vector<vector<int> > &tree,int a, int b, bool a_f){  // cout<<a<<":"<<b<<":"<<a_f<<endl;  if(res[a][b][a_f]!=-2) return res[a][b][a_f];  if(a==b) return res[a][b][a_f]=-1;  if(visit[a][b][a_f]) return 1;  //回溯(res[a][b][a_f]结果未必产生)  visit[a][b][a_f] = true;  int t=-3;  if(a_f){//a go    for(int i=0; i<tree[a].size(); i++){      int a1=tree[a][i];      t=dfs(tree, a1, b, false);      if(t==-1) break;     }    // if t==-3 or 1, then bob win    res[a][b][a_f]=t==-3?1:t;  }else{    for(int i=0; i<tree[b].size(); i++){      int b1=tree[b][i];      t=dfs(tree, a, b1, true);      if(t!=-1) break;    }    // if t==-3 or -1, then alice win    res[a][b][a_f]=t==-3?-1:t;  }  visit[a][b][a_f]=false;  return res[a][b][a_f];}int main(){    int cases; cin>>cases;     for(int casei=1; casei<=cases; casei++){      int n, m;      cin>>n>>m;      vector<vector<int> > tree(n, vector<int>());      for(int i=0; i<m; i++){        int a, b; cin>>a>>b; a--, b--;        tree[a].push_back(b);      }      memset(visit, 0, sizeof(visit));        for(int i=0; i<n; i++){        for(int j=0; j<n; j++){          for(int k=0; k<2; k++){            res[i][j][k]=-2;          }        }      }      int a, b; cin>>b>>a; a--, b--;      int s=dfs(tree, a, b, false);      cout<<"Case #"<<casei<<": ";      if(s==1) cout<<"Yes"<<endl;      else cout<<"No"<<endl;    }    return 0;}


0 0