久违的树形dp
dp[l][r] 表示在l到r之间字符串形成的子树有多少种
然后要枚举最左树枝所到位置 假设是 i 那么从l+1到i-1 递归就是最左树枝的种类 然后乘上剩下的部分
剩下的部分i到r相当是去掉了最左树枝的又一个子树,递归就可以
代码:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #define ll long long using namespace std; const ll MOD= 1000000000; const int N=305; ll dp[N][N]; char s[N]; ll dfs(int l,int r) { if(dp[l][r]!=-1) return dp[l][r]; if(l>r) return (dp[l][r]=0); if(l==r) return (dp[l][r]=1); if(s[l]!=s[r]) return (dp[l][r]=0); dp[l][r]=0; for(int i=l+1;i<=r;++i) if(s[i]==s[l]) dp[l][r]=(dp[l][r]+dfs(l+1,i-1)*dfs(i,r))%MOD; return dp[l][r]; } int main() { //freopen("data.in","r",stdin); while(scanf("%s",s)!=EOF) { int n=strlen(s); memset(dp,-1,sizeof(dp)); cout<<dfs(0,n-1)<<endl; } return 0; }