284. 金字塔
区间DP
将金字塔看成是树形结构,将所有字符串看成是最大的树,树是由多个子树构成
分割字符串,字符串个数必须是奇数才有可能构成完整的树 f [ i ][ j ] 中 a[ i ] == a[ j ]
区间 f[ i ][ j ] 分成两部分 f[ i ][ k ]和 f[ k+1 ][ j-1 ] , k-i+1 必须是奇数
区间 f[ i ][ j ]是由 f[ i ][ k ]和 f[ k+1 ][ j-1 ] 两个子树构成
#include<iostream>
#include<cstring>
#include<algorithm>
typedef long long ll;
const int N=310,MOD=1e9;
ll f[N][N];
char a[N];
int main()
{
int i,j,k,len,n,m;
scanf("%s",&a);
int la=strlen(a);
for(len=1;len<=la;len+=2)//房间数必须是奇数,并且最小是1
{
for(i=0;i<=la-len;i++)//从0开始,左端点
{
j=i+len-1;//右端点
if(len==1) f[i][j]=1;//当树大小为1时,房间数是1
else if(a[i]==a[j])//两个房间颜色必须相同才可能构成数
{
for(k=i;k<j;k+=2)//中间分割点距离左端点必须是奇数才能构成树
{
if(a[i]==a[k])//判断左端点和中间分割点颜色相同
f[i][j]=(f[i][j]+f[i][k]*f[k+1][j-1])%MOD;
}
}
}
}
printf("%lld\n",f[0][la-1]);
return 0;
}