一棵k层的二叉树,含有n个结点,每一个结点可能有0或者2个孩子,求全部可能的二叉树结构数对9901取余的结果。刚开始想到动态规划,可是没想出好的动态转移方程,后来想搜索,复杂度过高。无奈看告终题报告。ios
dp[i][j]表示i个结点能够组成的不超过j层的不一样二叉树的数量。一共i个结点,除了根结点,还有i-1个结点,左子树m个结点,右子树i-1-m个结点,左子树不超过j-1层的数量dp[m][j-1],右子树不超过j-1层的数量dp[i-1-m][j-1],所以dp[i][j]=dp[m][j-1]*dp[i-1-m][j-1],又由于m的取值为1,2,…,i-2,因此dp[i][j]= dp[1][j-1]*dp[i-2][j-1]+dp[2][j-1]*dp[i-3][j-1]+...+dp[i-2][j-1]*dp[1][j-1],即dp[i][j]=∑(dp[m][j-1]*dp[i-1-m][j-1])(m=1,2…,i-2)。web
/* ID: jzzlee1 PROG:nocows LANG:C++ */ //#include<iostream> #include<fstream> using namespace std; ifstream cin("nocows.in"); ofstream cout("nocows.out"); int dp[210][110]; int main() { int n,k; cin>>n>>k; int i,j,m; for(j=0;j<=k;j++)//设置边界条件 dp[1][j]=1; for(j=2;j<=k;++j) for(i=2;i<=n;++i) for(m=1;m<=i-1;++m) dp[i][j]=(dp[i][j]+dp[m][j-1]*dp[i-1-m][j-1])%9901;//递归求解 cout<<(dp[n][k]-dp[n][k-1]+9901)%9901<<endl; return 0; }