一个序列对应多少个多叉树遍历
dp[i][j]:s序列区间[i,j]序列对应的多叉树序列个数,枚举最左侧(第一个)分支,设第一个分支在序列第k个位置时回溯到根节点,枚举k的位置即可求出所有的多叉树
dp[i][j]=sum{dp[i+1][k-1]*dp[k][j],s[i]==s[k]==s[j],i+2<=k<=j} 边界:dp[i][i]=1
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#define maxn 50
#define maxm 1000
#define ll long long
#define sf scanf
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a))
const ll mod=1000000000;
#define clr(x) memset(x,0,sizeof(x))
using namespace std;
char s[400];
ll dp[410][410];
int main(){
//freopen("a.txt","r",stdin);
while(scanf("%s",s)!=EOF){
int len=strlen(s);
mem(dp,0);
for(int l=0;l<len;l++){//区间长度必须从小到大
for(int i=0;i<len&&i+l<len;i++){
int j=i+l;
if(i==j) dp[i][j]=1;
else
for(int k=i+2;k<=j;k++)
if(s[i]==s[j]&&s[i]==s[k])
dp[i][j]=(dp[i][j]+(dp[i+1][k-1]*dp[k][j])%mod)%mod;
}
}
printf("%lld\n",dp[0][len-1]);
}
}