zoukankan      html  css  js  c++  java
  • [USACO Section 2.3] Cow Pedigrees (动态规划)

    题目链接


    Solution

    我DP太菜啦...
    考虑到一棵二叉树是由根节点以及左儿子和右儿子构成。
    所以答案其实就是 左儿子方案数*右儿子方案数 。

    状态定义:
    (f[i][j]) 代表深度为 (i) ,节点个数为 (j) 的二叉树方案数。

    转移方程:
    对于每一个状态,节点总数已经确定。
    那么枚举一维左子树的节点个数,右边用总数减去。

    如果要构建一棵深度为 (i) 的二叉树,则两棵子树中必有一棵深度为 (i-1)
    此时有三种情况:

    1. 左子树深度小于 (i-1),右子树深度为 (i-1)
    2. 右子树深度小于 (i-1),左子树深度为 (i-1)
    3. 两边子树深度均为 (i-1)

    由于我们需要的是深度小于 (i-1) 的所有情况,所以记录一个前缀和 (sum)
    每一次要加上的便是 (sum_{i-2})

    然后参照以上做即可。

    Code

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=9901;
    int f[110][210],n,k,sum[110][210];
    
    int main()
    {
        scanf("%d%d", &n, &k);
        f[1][1]=1;
        for (int i=2;i<=k;i++)
            for (int j=1;j<=n;j++)
            {
                for (int p=1;p<j;p++)
                {
                    f[i][j]=(f[i][j]+sum[i-2][p]*f[i-1][j-p-1])%mod;
                    f[i][j]=(f[i][j]+sum[i-2][j-p-1]*f[i-1][p])%mod;
                    f[i][j]=(f[i][j]+f[i-1][p]*f[i-1][j-p-1])%mod;
                }
                sum[i-1][j]=(sum[i-2][j]+f[i-1][j])%mod;
            }
        printf("%d
    ", f[k][n]);
    
        return 0;
    }
    
    
  • 相关阅读:
    将kali linux装入U盘 制作随身携带的kali linux
    arch/manjaro linux configuration
    python资源

    JSP通过AJAX获取服务端的时间,在页面上自动更新
    Spark基础
    MapReduce基础
    HDFS基础
    C#输出杨辉三角形
    Java窗体居中显示的2种方法
  • 原文地址:https://www.cnblogs.com/Kv-Stalin/p/9647575.html
Copyright © 2011-2022 走看看