zoukankan      html  css  js  c++  java
  • USACO2.3.2Cow Pedigrees

    Cow Pedigrees

    Silviu Ganceanu -- 2003

    Farmer John is considering purchasing a new herd of cows. In this new herd, each mother cow gives birth to two children. The relationships among the cows can easily be represented by one or more binary trees with a total of N (3 <= N < 200) nodes. The trees have these properties:

    • The degree of each node is 0 or 2. The degree is the count of the node's immediate children.
    • The height of the tree is equal to K (1 < K <100). The height is the number of nodes on the longest path from the root to any leaf; a leaf is a node with no children.

    How many different possible pedigree structures are there? A pedigree is different if its tree structure differs from that of another pedigree. Output the remainder when the total number of different possible pedigrees is divided by 9901.

    PROGRAM NAME: nocows

    INPUT FORMAT

    • Line 1: Two space-separated integers, N and K.

    SAMPLE INPUT (file nocows.in)

    5 3
    

    OUTPUT FORMAT

    • Line 1: One single integer number representing the number of possible pedigrees MODULO 9901.

    SAMPLE OUTPUT (file nocows.out)

    2
    

    OUTPUT DETAILS

    Two possible pedigrees have 5 nodes and height equal to 3:

               @                   @      
              / \                 / \
             @   @      and      @   @
            / \                     / \
           @   @                   @   @
    吐槽:总想着把各种符合情况的树都构造出来,不过想了N久都不知道怎么构造。然后只好看题解。方法是DP,看到DP就蛋疼。。。总是不知道怎么推DP方程。所以DP方程也不是自己YY的,悲剧呀。不过思路倒是弄清楚了,知道方程怎么推出来的。现在暂时只能这样,尽量保证代码是独立完成的,慢慢来好了,真是无奈呀,等刷完USACO,就去刷DP专题,希望能够有所进步,春君加油啦!
    解题思路:一棵树可以由两个子树和一个根节点构造而来,这个是解题核心(怎么就想不到呢,真是太笨了),知道这个就好推DP方程了。f[i][j]表示i个节点组成深度不超过j的二叉树的数量。两个子树的总节点数为i-1,假设左子树总节点数为m,那么右子树总节点数为i-1-m。f[m][j-1]表示为左子树深度最多为j-1层的二叉树的数量,f[i-1-m][j-1]则表示右子树深度最多为j-1层的二叉树的数量。
    那么根据乘法原理f[i][j]=f[m][j-1]*f[i-1-m][j-1](m=1...i-2)(m肯定为奇数)。
    即DP方程为:f[i,j]=∑(f[m,j-1]×f[i-1-m,j-1])(m∈{1..i-2})
    那我们的最终答案就是f[n][k]-f[n][k-1]。这个式子表示节点数为n深度不超过k的二叉树数量减去节点数为n深度不超过k-1的二叉树数量,即节点数为n深度恰好为k的二叉树的数量。不过由于题目要求要模9901,这个表达式可能是负,输出时要注意。
    View Code
     1 /*
     2 ID:spcjv51
     3 PROG:nocows
     4 LANG:C
     5 */
     6 #include<stdio.h>
     7 #include<string.h>
     8 int f[205][105];
     9 int main(void)
    10 {
    11     freopen("nocows.in","r",stdin);
    12     freopen("nocows.out","w",stdout);
    13     int i,j,k,m,n;
    14     scanf("%d%d",&n,&k);
    15     memset(f,0,sizeof(f));
    16     for(j=1;j<=k;j++)
    17     f[1][j]=1;
    18     for(j=2;j<=k;j++)
    19     for(i=2;i<=n;i++)
    20         for(m=1;m<=i-2;m+=2)
    21         f[i][j]=(f[i][j]+f[m][j-1]*f[i-m-1][j-1])%9901;
    22     printf("%d\n",(f[n][k]-f[n][k-1]+9901)%9901);
    23     return 0;
    24 }
     
  • 相关阅读:
    【MM系列】SAP库龄报表逻辑理解
    【MM系列】SAP技巧之更改布局
    【MM系列】SAP里批量设置采购信息记录删除标记
    《跃迁-从技术到管理的硅谷路径》读书笔记
    Java安全编码标准
    web安全/渗透测试--1--web安全原则
    使用spring validation完成数据后端校验
    9 个Java 异常处理的规则
    程序员必看:给你一份详细的Spring Boot知识清单
    Java架构技术知识点梳理
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/2910297.html
Copyright © 2011-2022 走看看