2288-Oh, My Goat!
Oh, My Goat! | Aizu Online Judge
本番では解けなかった問題
解法
メモ化再帰.
現在のノードと何文字目かでDFS
600*5*600*5だとメモリが足りなくなるので,二つ目のグラフにおいて0文字目の時のみメモするようにする.
実装(C++)
#include <iostream> #include <vector> #include <algorithm> #include <cstring> using namespace std; int MOD=1000000007; struct Edge{ int src,dst; string s; }; int n[2],m[2]; vector<int> G[2][600]; Edge edge[2][600]; int dp[600][5][600]; int dfs(int now1,int x1,int now2,int x2); int dfs2(int now1,int x1,int now2,int x2){ char t=edge[0][now1].s[x1]; int ans=0; if(edge[1][now2].s.size()==x2+1){ for(int i=0;i<G[1][edge[1][now2].dst].size();i++){ Edge &next=edge[1][G[1][edge[1][now2].dst][i]]; if(next.s[0]==t){ ans+=dfs(now1,x1,G[1][edge[1][now2].dst][i],0); ans%=MOD; } } }else{ if(edge[1][now2].s[x2+1]==t){ ans+=dfs(now1,x1,now2,x2+1); ans%=MOD; } } return ans; } int dfs(int now1,int x1,int now2,int x2){//現在いる頂点,1を進める if(x2==0){ if(dp[now1][x1][now2]>=0)return dp[now1][x1][now2]; } int ans=0; if(edge[0][now1].s.size()==x1+1){ if(edge[0][now1].dst==n[0]-1&&edge[1][now2].s.size()==x2+1&&edge[1][now2].dst==n[1]-1)return 1; for(int i=0;i<G[0][edge[0][now1].dst].size();i++){ ans+=dfs2(G[0][edge[0][now1].dst][i],0,now2,x2); ans%=MOD; } }else{ ans+=dfs2(now1,x1+1,now2,x2); ans%=MOD; } if(x2==0)dp[now1][x1][now2]=ans; return ans; } int main() { int T; for(cin>>T;T--;){ for(int i=0;i<2;i++){ cin>>n[i]>>m[i]; for(int j=0;j<n[i];j++){ G[i][j]=vector<int>(); } for(int j=0;j<m[i];j++){ int a,b;string c; cin>>a>>b>>c; edge[i][j]=(Edge){a,b,c}; G[i][a].push_back(j); } } memset(dp,-1,sizeof(dp)); int ans=0; for(int i=0;i<G[0][0].size();i++){ for(int j=0;j<G[1][0].size();j++){ if(edge[0][G[0][0][i]].s[0]==edge[1][G[1][0][j]].s[0]){ ans+=dfs(i,0,j,0); ans%=MOD; } } } cout<<ans<<endl; } return 0; }