这是一道考思维的好题。
一开始设f[i][j]是i个点刚好j层的方案数,死活调不出来,看题解发现可以改为<=j层的方案数,最后输出f[n][m]-f[n][m-1]就好了。
对于计算考虑左右子树分配,设i个点分给左子树,j个点分配右子树,注意枚举顺序,乘法原理搞一搞就好。
我拼尽全力只得了57分,qwq。
#include<cstdio> #include<cstring> #include<cctype> #include<algorithm> #include<cstdlib> #include<cmath> #define mod 9901 #define maxn 250 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } int f[maxn][maxn]; int s[maxn][maxn]; int n,m; int main(){ n=read(),m=read(); for(int i=1;i<=m;++i) f[1][i]=1; for(int j=1;j<=m;++j){ for(int i=1;i<=n;++i){ int &o=f[i][j]; for(int k=1;k<i-1;++k) o=(o+f[k][j-1]*f[i-k-1][j-1])%mod; } } printf("%d ",(f[n][m]-f[n][m-1]+mod)%mod); return 0; }