USACO 2.3.2 Cow Pedigrees

Cow Pedigrees

Silviu Ganceanu -- 2003

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

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

How many different possible pedigree structures are there? Apedigree is different if its tree structure differs from that ofanother pedigree. Output the remainder when the total number ofdifferent 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 possiblepedigrees MODULO 9901.

SAMPLE OUTPUT (file nocows.out)

2

OUTPUT DETAILS

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

分析:要计算节点数为N深度为K的树的表示方法有多少种,可以把从第1层到第K-1层的二叉树分为两部分,去掉根节点,就变成了两颗二叉树,左边的树有k个节点,则右边的节点有N-1-k个节点,假设左边k个节点有a种表示方法,右边N-1-k个节点b种表示方法,所以共有a*b种方法,枚举k从1到N-2的情况累加,得到的就是小于等于k层的N个节点的表示方法的数目。所以K层N个节点的表示方法就是小于等于k层的N个节点的表示方法的数目-小于等于k-1层的N个节点的表示方法的数目。

源代码:

/*
ID: supersnow0622
PROG: nocows
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <string>
#include<memory.h>
using namespace std;
int dp[210][110];
int main() {
    ofstream fout ("nocows.out");
    ifstream fin ("nocows.in");
    int N,K;
    cin>>N>>K;
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=K;i++)
      for(int j=1;j<=N;j+=2)
      {
         if(j==1)dp[j][i]=1;
         for(int k=1;k<=j-2;k+=2)
           dp[j][i]=(dp[j][i]+dp[k][i-1]*dp[j-1-k][i-1])%9901;
      }
    cout<<(dp[N][K]-dp[N][K-1]+9901)%9901<<endl;
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值