首先如果这是一棵二叉树,是不是很显然?只要枚举左右子树即可,时间复杂度为O(n^3)。可惜题目中不是棵二叉树,所以我们就把它转换为二叉树!按照左儿子右兄弟的方式进行构造,我们发现它的dfs序与原本的树是相同的!

我写了记忆化,但其实也可以直接区间

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2000009;
const ll mo=998244353;
int n,a[maxn];
ll dp[1000][1000];
ll dfs(int l,int r)
{
    if (l==r) return 1ll;
    if (dp[l][r]!=-1) return dp[l][r];
    ll ans=0;
    for (int i=l;i<=r;i++)
    {
        if (i==r) ans=(ans+dfs(l+1,r))%mo;
        else if ((i==l)&&(a[l]<a[l+1])) ans=(ans+dfs(l+1,r))%mo;
        else if (a[l]<a[i+1])ans=(ans+(dfs(l+1,i)*dfs(i+1,r))%mo)%mo;
    }
    dp[l][r]=ans;
    //cout<<l<<" "<<r<<" "<<ans<<endl;
    return ans;
}
int main()
{
    cin>>n;
    for (int i=1;i<=n;i++) cin>>a[i];
    for (int i=1;i<=n;i++)
    for (int j=1;j<=n;j++)
    dp[i][j]=-1;
    cout<<dfs(2,n)<<endl;
    return 0;
}

 

posted on 2022-05-22 11:57  nhc2014  阅读(48)  评论(0编辑  收藏  举报