LA 3516 Exploring Pyramid
题目链接:LA 3516
题目大意:这个题目指的是有一个长度为n(n<=300)的字符串,是一棵多叉树从根开始遍历整棵树最后又回到根的序,问这样的序一共有多少种,答案对1e9取模,对于两条不同的链,如果它们的位置交换,则被考虑为两种情况,例如:
这就是两种不同的情况。
题目分析:对于这道题目,我们可以想到应该是一道计数问题,对于一段首尾字符相同的子串,我们认为他是某一棵子树完成自身的遍历,而他可能有不止一个分支,因此可能在遍历过程中回到过根,因此我们还要找出其中可能回到根的位置再次进行转移,伪代码如下:
for(i,j 枚举每个区间)
for(k=i+2 to j)
if(s[i]==s[k])
dp[i,j]=(dp[i,j]+dp[i+1,k-1]*dp[k,j])%MOD
注意在将区间i,j分开相乘的过程中可能会(一定会 )爆int,因此可以直接把dp开成long long,完整代码如下:
#include<stdio.h>
#include<algorithm>
#include<string.h>
#define LL long long
char str[330];
int n,m,ans,MOD=1000000000;
LL dp[330][330];
int main()
{
while(scanf("%s",str)!=EOF){
memset(dp,0,sizeof(dp));
for(int i=strlen(str);i>=0;i--)
str[i+1]=str[i];
n=strlen(str)-1;
for(int i=1;i<=n;i++)dp[i][i]=1;
for(int j=1;j<=n;j++){
for(int i=1;i<=n;i++){
if(i+j>n)break;
if(str[i]^str[i+j])continue;
for(int k=i+2;k<=i+j;k++){
if(str[k]==str[i])
dp[i][i+j]=(dp[i][i+j]+dp[i+1][k-1]*dp[k][i+j])%MOD;
}
}
}
printf("%lld\n",dp[1][n]);
}
return 0;
}