奇异家庭

题目:

有一种奇怪的大家族,这种家族里的人要么没有孩子,要么就有两个孩子。已知某个这种家族共有N个人,家族中共有K代人。你能告诉我这样的一个家族可能的家谱结构的种数除以9901的余数是多少吗?

输入包括一行,包括两个被空格分开的整数,第一个为家族中的人数N(3≤N≤200),第二个为家族中的代数K(1 < K < 100)。

输出仅一行,包含一个整数,表示这样的一个家族可能的家谱结构的种数除以9901的余数。

样例输入

5 3

样例输出

2

这道题目用的还是动态规划的思想:因为以结点n为根节点的树的结构中暑等于以n为父节点的左子树的结构个数乘以以n为父节点的右字数的结构个数,现在定义状态转移:dp[i][j]的含义是:树有i个结点,在不超过j层的情况下的排列个数。那么dp[i][j]=dp[m][j-1]*dp[i-m-1][j-1],方程式右边第一项代表左子树的结构个数,第二项是右字树的结构个数,又由于m的取值范围是1到i-2的所以dp[i][j]为右式的求和。

代码:

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
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)//第i层
for(i=2;i<=n;++i) //一共有n个节点
for(m=1;m<=i-1;++m) //左边m个,右边i-m-1个
dp[i][j]=(dp[i][j]+dp[m][j-1]*dp[i-1-m][j-1])%9901;
//用i个节点组成j层 是原本的加上 由m个节点组成j-1层 和i-m-1个组成j-1个 的乘积
cout<<(dp[n][k]-dp[n][k-1]+9901)%9901<<endl;//n个节点组成k个
return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39996728/article/details/79888266