CF 289 F. Progress Monitoring DP计数

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;
}



 

posted @ 2019-03-08 20:50  zhangxianlong  阅读(147)  评论(0)    收藏  举报