• 奇异的家族-动态规划


    有一种奇怪的大家族,这种家族里的人要么没有孩子,要么就有两个孩子。已知某个这种家族共有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;
    }

  • 相关阅读:
    SQL 使用identity(int,1,1)来产生行号。
    SQL DateName\DatePart 返回表示指定date的指定datepart的字符串
    让我们受用一生的好习惯
    SCRUM软件开发过程(转)
    计算机英语词汇
    oral English英语绕口令(转)
    Setup相关经验总结
    与老外吵架之必会109句
    BAT批处理文件语法(转)
    SQL Server 2005之PIVOT/UNPIVOT行列转换(转)
  • 原文地址:https://www.cnblogs.com/kuroko-ghh/p/9363382.html
Copyright © 2020-2023  润新知