USACO 2.3 Cow 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      @   @
        / \                     /        @   @                   @   @

————————————————————————题解其实一眼就是dp啊……但是我dp弱成渣了哎呀自己辣么久都没有刷USACO了呢……趁着国庆赶紧第二章结业吧……其实一开始都没有想出来怎么搞,然后看别人题解说从下往上搞好机智啊这样真的……然后就会了……首先呢我们转移时相当于在两个子树上加一个根节点,但是相同高度节点数相同的子树再合并的话就一次如果高度不同的话就两次,因为位置可以交换枚举高度要花m个时间,然后就会T,所以我们记录个前缀和然后就可以秒过了
 1 /*
 2 ID: ivorysi
 3 PROG: nocows
 4 LANG: C++
 5 */
 6
 7 #include <iostream>
 8 #include <string.h>
 9 #include <cstdlib>
10 #include <cstdio>
11 #include <algorithm>
12 #include <cstring>
13 #include <vector>
14 #include <ctime>
15 #include <cmath>
16 #include <queue>
17 #define ivorysi
18 #define mo  1000000007
19 #define siji(i,x,y) for(int i=(x);i<=(y);i++)
20 #define gongzi(j,x,y) for(int j=(x);j>=(y);j--)
21 #define xiaosiji(i,x,y) for(int i=(x);i<(y);i++)
22 #define sigongzi(j,x,y) for(int j=(x);j>(y);j--)
23 #define ivory(i,x) for(int i=head[x];i;i=edge[i].n)
24 #define pii pair<int,int>
25 #define fi first
26 #define se second
27 #define inf 0x5f5f5f5f
28 #define N 5005
29 typedef long long ll;
30 using namespace std;
31 int dp[205][105];
32 int g[205][105];
33 int n,m;
34 int main(int argc, char const *argv[])
35 {
36 #ifdef ivorysi
37     freopen("nocows.in","r",stdin);
38     freopen("nocows.out","w",stdout);
39 #else
40     freopen("f1.in","r",stdin);
41 #endif
42     scanf("%d%d",&n,&m);
43     dp[1][1]=1;
44     g[1][1]=1;
45     siji(i,2,m) {
46         siji(j,1,n) {
47             if(j+2>n) break;
48             siji(k,1,n) {
49                 if(j+k+1>n) break;
50                 dp[j+k+1][i]=(1LL*dp[j+k+1][i]+1LL*dp[j][i-1]*dp[k][i-1])%9901;
51             }
52         }
53
54         if(i-2>=1) {
55             siji(j,1,n) {
56                 if(j+2>n) break;
57                 siji(k,1,n) {
58                     if(j+k+1>n) break;
59                     dp[j+k+1][i]=(1LL*dp[j+k+1][i]+1LL*dp[j][i-1]*g[k][i-2]*2)%9901;
60                 }
61             }
62         }
63         siji(l,1,n) g[l][i]=(g[l][i-1]+dp[l][i])%9901;
64         //一开始这句话的位置放错了,应该这一个高度算完之后再记录,否则会比较小
65     }
66     printf("%d\n",dp[n][m]%9901);
67     return 0;
68 }
				
时间: 2024-10-09 00:11:00

USACO 2.3 Cow Pedigrees的相关文章

USACO Section2.3 Cow Pedigrees 解题报告 【icedream61】

nocows解题报告------------------------------------------------------------------------------------------------------------------------------------------------[题目] 给你N个点,生成一棵K层的树,有s种情况.请输出s%9901的值. 要求很简单,每个点只能有0个或2个孩子.[数据范围] 3<=N<200 1<K<100[输入格式]

洛谷P1472 奶牛家谱 Cow Pedigrees

P1472 奶牛家谱 Cow Pedigrees 102通过 193提交 题目提供者该用户不存在 标签USACO 难度普及+/提高 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 农民约翰准备购买一群新奶牛. 在这个新的奶牛群中, 每一个母亲奶牛都生两个小奶牛.这些奶牛间的关系可以用二叉树来表示.这些二叉树总共有N个节点(3 <= N < 200).这些二叉树有如下性质: 每一个节点的度是0或2.度是这个节点的孩子的数目. 树的高度等于K(1 < K < 100).高度是从

usaco Cow Pedigrees

题意是,求N,个节点,组成高度为K的二叉树,形态有多少,且每个节点的度要么为0要么为2. 这题第一眼看后就知道要dp,但却没找到方程,看了别人题解之后才知道,原来是从分治的思想出发的. dp[i][j]的意思是用i个节点组成高度不超过j的二叉树的形态,那么dp[i][j]=dp[i][j]+dp[k][j-1]*dp[i-1-k][j-1],k=1,3,5..... 就是去掉根节点之后,求出左子树节点个数为k的形态数,乘上右子树节点个数为i-1-k时的形态数. 输出dp[N][K]-dp[N][

USACO Cow Pedigrees 【Dp】

一道经典Dp不过现在还不是能特别理解. 定义dp[i][j] 表示由i个节点,j 层高度的累计方法数 状态转移方程为: 用i个点组成深度最多为j的二叉树的方法树等于组成左子树的方法数 乘于组成右子树的方法数再累计. 暂贴代码: /* ID: wushuai2 PROG: nocows LANG: C++ */ //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h>

【USACO】Cow Pedigrees(DP)

dp[i][j]代表总结点数为i的,高度不超过j的树的种类 dp[i][j] += dp[k][j] * dp[i - k - 1][j]; 注意取余的情况 结果为 dp[n][k] - dp[n][k - 1] /* ID: 18906421 LANG: C++ PROG: nocows */ #include<cstdio> using namespace std; const int maxn = 205; const int mod = 9901; int n,k; int dp[ma

USACO 2.4 Cow Tours

Cow Tours Farmer John has a number of pastures on his farm. Cow paths connect some pastures with certain other pastures, forming a field. But, at the present time, you can find at least two pastures that cannot be connected by any sequence of cow pat

Cow Pedigrees

Two possible pedigrees have 5 nodes and height equal to 3: @ @ / \ / @ @ and @ @ / \ / @ @ @ @ 题意:给你 n 个元素,可以组成多少颗深度为 m 的二叉树,每个结点的度只有 0 或 2 . 果然不好下手就是DP题.本题DP状态定义就显得十分重要了.如果直接定义dp[i][j] 表示 用i个元素 深度为j的二叉树.发现并不好转移.于是 别人就想到了 定义dp[i][j]表示 用i个元素按 深度小于等于j的

[luoguP1472] 奶牛家谱 Cow Pedigrees(DP)

传送门 一个深度为i的树可以由一个根节点外加两个深度为i-1的树组成,这就决定了DP该怎么写. 然而我真的没有想到. f[i][j]表示深度为i节点数为j的个数 sum[i][j]表示深度小于等于i节点树为j的个数 #include <cstdio> #define N 402 #define p 9901 int n, m; int f[N][N], sum[N][N]; //f[i][j]表示深度为i节点数为j的个数 //sum[i][j]表示深度<=i节点数为j的树的个数 int

2.3.2 COW PEDIGREES 奶牛家谱

解题思路: 1.简单动态规划.基本思想是用小的二叉树去组成大的二叉树,最后输出dp[k][n]-dp[k-1][n]恰好就是要求的n个 点组成深度最多为k的方法数 2.设dp[i][j]表示j个点组成深度最多为i的二叉树的方法数,则动态规划公式为: dp[i][j]=∑(dp[i-1][l]*dp[i-1][j-1-l])(1<=l<=j-2) dp[i][1]=1 3.注意:点的个数总为奇数. 核心代码: for(i=1;i<=k;i++) dp[i][1]=1; for(i=1;i&