题解:UVA1362 Exploring Pyramids
双倍经验:P10956。
Solution UVA1362
Problem
给定一棵树的 dfs 遍历顺序,求其可能对应的树的个数。
Idea
不难发现每一次我们到达一个点,都会立即开始遍历它的子树,经过若干次遍历再回到这个点,然后进行遍历它的下一个子树(如果没有子树了就返回父亲)。
因此,一个树的 dfs 遍历序列一定形如 。
还不理解?看图:

我们从点 出发,设遍历序列为 。
先遍历到 ,。
然后遍历到 ,。
然后回到 ,。
然后依次遍历 、、,最后回到 ,则 。
然后遍历子树 和 ,则 。
因此,我们发现一个数 一定会在遍历序列中输出 次(其中 为 的儿子的个数)。
我们发现每个子树都是相互独立的,即一个子树的统计结果不会影响没有包含关系的另一个子树的统计结果。
这个信息显然是可合并的,所以可以区间 。
设 为 区间的方案数。
则显然有:,其中 且 。
解释一下就是枚举断点,使得 和 变为两个不同子树。
答案就是 。
Code
#include<bits/stdc++.h>
using namespace std;
const int N=305,mod=1000000000;
string s;
int n;
long long dp[N][N];
int main(){
while(cin>>s){
n=s.length();
s=' '+s;
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)dp[i][i]=1ll;
for(int len=2;len<=n;len++){
for(int i=1,j=len;j<=n;j++,i++){
if(s[i]!=s[j])continue;
for(int k=i;k<j;k++){
if(s[k]!=s[i])continue;
dp[i][j]=dp[i][j]+dp[i][k]*dp[k+1][j-1]%mod;
dp[i][j]%=mod;
}
}
}
printf("%lld\n",dp[1][n]);
}
return 0;
}

浙公网安备 33010602011771号