http://codeforces.com/problemset/problem/509/F
题目大意:给出一个遍历树的程序的输出的遍历顺序b序列,问可能的树的形态有多少种。
思路:记忆化搜索
其中我们枚举第一个子树的大小,然后后面的其他子树可以继续分解。
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #include<iostream> 6 #define ll long long 7 const ll Mod=1000000007; 8 int a[200005]; 9 ll f[5005][5005]; 10 int read(){ 11 int t=0,f=1;char ch=getchar(); 12 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 13 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 14 return t*f; 15 } 16 ll dfs(int l,int r){ 17 if (l>=r){ 18 return (f[l][r]=1); 19 } 20 if (f[l][r]!=-1){ 21 return f[l][r]; 22 } 23 ll res=0; 24 for (int i=l+1;i<=r;i++) 25 if (i==r||a[l+1]<a[i+1]) 26 { 27 res=(res+((dfs(l+1,i)*dfs(i,r)))%Mod)%Mod; 28 } 29 return f[l][r]=res; 30 } 31 int main(){ 32 int n=read(); 33 for (int i=1;i<=n;i++) 34 for (int j=1;j<=n;j++) 35 f[i][j]=-1; 36 for (int i=1;i<=n;i++) a[i]=read(); 37 printf("%I64d ",dfs(1,n)); 38 return 0; 39 }