USACO2.3.2 Cow Pedigrees 奶牛家谱(DP)

本文探讨了在一个特殊的二叉树模型下,如何计算符合特定节点数和高度限制的不同家谱树的数量。通过使用动态规划的方法,我们能够有效地解决这个问题,并提供了一个具体的AC代码实现,展示了状态转移方程和滚动数组的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description
农民约翰准备购买一群新奶牛。 在这个新的奶牛群中, 每一个母亲奶牛都生两小奶牛。这些奶牛间的关系可以用二叉树来表示。这些二叉树总共有N个节点(3 <= N < 200)。这些二叉树有如下性质: 每一个节点的度是0或2。度是这个节点的孩子的数目。 树的高度等于K(1 < K < 100)。高度是从根到任何叶子的最长的路径上的节点的数目; 叶子是指没有孩子的节点。 有多少不同的家谱结构? 如果一个家谱的树结构不同于另一个的, 那么这两个家谱就是不同的。输出可能的家谱树的个数除以9901的余数。

Input
第1行: 两个空格分开的整数, N和K。

Output
第 1 行: 一个整数,表示可能的家谱树的个数除以9901的余数。

Sample Input
5 3
Sample Output
2

OUTPUT DETAILS:
有5个节点,高为3的两个不同的家谱:

层数第一种第二种
1根节点根节点
2左节点数1右节点数1左节点数1右节点数1
3左节点数2右节点数1左节点数1右节点数2

已知整个树的节点必定为2n−12n-12n1( 每一个母亲奶牛都生两小奶牛),去掉根节点就是2n2n2n,现在设整棵树共nnn个节点,由xxx个左子树构成,那么右子树个数就为n−1−xn-1-xn1x个,dp[i][j]dp[i][j]dp[i][j]表示深度为iii最多用jjj个点组成的二叉树的个数,则状态转移方程dp[i][j]=dp[i][j]+dp[i−1][l]∗dp[i−1][r]dp[i][j] = dp[i][j]+dp[i-1][l]*dp[i-1][r]dp[i][j]=dp[i][j]+dp[i1][l]dp[i1][r],表示深度为iii节点为jjj的树能由深度为i−1i-1i1节点数之和为j−1j-1j1的树组成(在两颗树的根节点上再加一个根节点连接深度就+1+1+1了) 其中lll,rrr为左右子树个数,满足r+l=n−1r+l=n-1r+l=n1lllrrr一定为奇数(二叉树性质)。


AC代码
我这里用2个一维数组滚动求的值,因为对于深度为xxx的树只需要知道深度为x−1x-1x1的所有情况即可,最后相减便是答案,需要注意的是相减求模得先加要模的值,防止相减为负数的这种情况

#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
#include <iostream>
#include <sstream>
#include <algorithm>
#define _mem(a,b) memset(a,0,(b+3)<<2)

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int inf = 0x3f;
const double EPS = 1e-7;
const double Pi = acos(-1);
const int MOD = 9901;
const int maxn =  2*1e2+9;

int dp[maxn];
int res[maxn];
int main() {
    int a,b;
    cin >> a >> b;
    res[1] = 1;             ///这里res为第一层,dp数组是从第二层开始的所以循环-1
    for(int i=1;i<=b-1;i++){    
        _mem(dp,a);        ///dp数组初始化为0
        dp[1] = 1;
        for(int j=3;j<=a;j+=2)
            for(int k=1;k<=j-2;k+=2)
                dp[j] = (dp[j]+res[k]*res[j-1-k])%MOD;  ///递推式
        if(i!=b-1)
            memcpy(res,dp,(a+3)<<2);    ///滚动,数组拷贝
    }
    cout << (dp[a]-res[a]+MOD)%MOD << endl;
    return 0;
}

转载于:https://www.cnblogs.com/bestsort/p/10588830.html

### USACO Competition Problem Solutions for Cow Games In the context of USACO competitions, problems involving cows often require a blend of algorithmic thinking and mathematical insight. For instance, one notable problem involves Farmer John providing hay to his cows on different days with varying quantities[^3]. This type of scenario can be modeled using dynamic programming or greedy algorithms depending on what is asked. For specific game-related challenges featuring cows within USACO contests, consider an example where cows play games that involve strategic decision-making under given constraints. These scenarios frequently test contestants&#39; ability to apply concepts like graph theory, number manipulation, and optimization techniques effectively. A relevant exercise from similar competitive coding platforms includes dealing with round numbers which have properties making them interesting subjects for computational puzzles[^2]: ```python def count_round_numbers(n): binary_representation = bin(n)[2:] zero_count = binary_representation.count(&#39;0&#39;) return zero_count >= len(binary_representation) / 2 ``` This function checks whether a number has at least as many zeros as ones in its binary representation—a concept sometimes explored through playful contexts such as virtual cow activities designed around numerical patterns. To tackle these kinds of tasks successfully: - Understand all rules governing how elements interact. - Identify efficient ways to represent data structures involved. - Develop strategies based on observed trends or established theories applicable to the situation described.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值