奇异的家族-动态规划

有一种奇怪的大家族,这种家族里的人要么没有孩子,要么就有两个孩子。已知某个这种家族共有N个人,家族中共有K代人。你能告诉我这样的一个家族可能的家谱结构的种数除以9901的余数是多少吗?
输入包括一行,包括两个被空格分开的整数,第一个为家族中的人数N(3≤N≤200),第二个为家族中的代数K(1 < K < 100)。
输出仅一行,包含一个整数,表示这样的一个家族可能的家谱结构的种数除以9901的余数。
样例1
输入:
5 3
输出:
2

回答:这个题目很销魂。真正有意义的题干就一句话:有一种奇怪的大家族,这种家族里的人要么没有孩子,要么就有两个孩子。已知某个这种家族共有N个人,家族中共有K代人。

估计题目的作者在这里想定义了一种二叉树(节点要么没有孩子,要么有两个孩子)。想必作者对族谱结构并不熟悉,族谱上是存在双亲的,不可能是二叉树。

这个先不说,看作者是怎么定义族谱结构的,我只能按照两个样例去猜:

奇异的家族-动态规划

为什么会有特殊情形呢?这是我用了好几组数据求结果,为了寻求解释的一致性得出的结论。

题目本身对N个人的解释是存在矛盾之处的:

  1. 在族谱的垂直层次上,N个人是不分长辈晚辈的,交换两个节点族谱不变

  2. 在族谱的水平层次上,对称时,叶子结点是不分兄弟的;不对称时,又是区分的

参考了别人的代码,自己不是很懂。答案来源https://my.oschina.net/u/347565/blog/63684
#include
#include
#define N 201
#define MOD 9901
using namespace std;
int dp[N][N], n, k; //
int main()
{
    cin>>n>>k;
    memset(dp, 0, sizeof(dp));
    for (int i = 1; i <= k; i++)
    {
        dp[1][i] = 1;
    }
    for (int i = 2; i <= k; i++)
    {
        for (int j = 3; j <= n; j += 2)
        {
            for (int p = 1; p <= j - 2; p += 2)
            {
                dp[j][i] = (dp[j][i] + dp[p][i - 1] * dp[j - p - 1][i - 1])
                           % MOD;
            }
        }
    }
    cout<<(dp[n][k] - dp[n][k - 1] + MOD) % MOD<<endl;
}

原文地址:https://www.cnblogs.com/kuroko-ghh/p/9363382.html