UVALive3516Exploring Pyramids(dp)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
题目意思:有一棵多叉树,每个结点的子节点有左右之分(即要按照顺序查找),从跟结点开始遍历,尽量往左走,走不通就回溯,每到一个结点就记录下结点的信息,最终可以得到一个序列。
所要求的即为给定一个序列,有多少棵树与之对应。
dp[i][j]表示从序列的第i个到第j个所构成的分支的方案数,
边界情况为dp[i][i]=1;如果s[i]!=s[j],则dp[i][j]=0;
递推关系式为dp[i][j]=∑(dp[i+1][k-1]*dp[k][j]);i+2≤k≤j,s[i]=s[j]=s[k];
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 string s; 5 long long dp[310][310]; 6 const long long MOD=1000000000; 7 long long dfs(int i,int j) 8 { 9 if(i==j)return 1; 10 if(s[i]!=s[j])return 0; 11 if(dp[i][j]>=0)return dp[i][j]; 12 dp[i][j]=0; 13 for(int k=i+2;k<=j;k++) 14 { 15 if(s[i]==s[k]) 16 dp[i][j]=(dp[i][j]+dfs(i+1,k-1)*dfs(k,j))%MOD; 17 } 18 return dp[i][j]; 19 } 20 int main() 21 { 22 ios::sync_with_stdio(false); 23 while(cin>>s) 24 { 25 memset(dp,-1,sizeof(dp)); 26 cout<<dfs(0,s.length()-1)<<endl; 27 } 28 return 0; 29 }