http://codeforces.com/contest/509/problem/F
题意:给出DFS “先序”输出顺序,问有多少种树满足条件
思路:DP[i][j] 表示以 i 为根,i+1 ~ j 是 i 的子树的方案数目,
则有转移方程
DP[ i ][ j ] = DP[ i+1 ][ j ] + Σ DP[ i+1 ][ k ] * DP[ k ] [ j ] {其中a[ k+1 ] > a [ i+1 ] }
注意的是这里并不是说明只把i节点连接两个子树,而是将第一个子树当作一个,其他的当作另一个(假借k为根)
代码:
#include<bits/stdc++.h>
#define X first
#define Y second
#define PB push_back
#define LL long long
#define VI vector<int>
#define pii pair<int,int>
#define MEM(x,y) memset(x,y,sizeof(x))
#define bug(x) cout<<"debug "#x" is "<<x<<endl;
#define FIO ios::sync_with_stdio(false);
using namespace std;
const int maxn=1e3+7;
const int mod=1e9+7;
int a[maxn];
int dp[maxn][maxn];
string s;
LL add(const LL &a,const LL &b){return (a+b)%mod;};
LL mul(const LL &a,const LL &b){return (a*b)%mod;};
int DP(int L,int R){
if(dp[L][R]!=-1)return dp[L][R];
if(L>=R) return dp[L][R]=1;
int ret=DP(L+1,R);
for(int k=L+1;k<=R;k++)
if(a[L+1]<a[k])
ret=add(ret,mul(DP(L+1,k-1),DP(k-1,R)));
return dp[L][R]=ret;
}
int main(){
ios::sync_with_stdio(false);
int n;
MEM(dp,-1);
string tmp;
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
cout<<DP(0,n-1)<<endl;
}