USACO Section 2.3 Cow Pedigrees - DP状态还是很好找的.

本文介绍了一个基于动态规划(DP)算法解决特定二叉树计数问题的方法。通过定义状态dp[n][k]来表示由n个节点构成、深度为k的二叉树的数量,并详细阐述了状态转移的过程,包括枚举子树节点数量和层级来更新状态值。

这道题一看就是DP...状态的话用dp[n][k]表示n个点k层且符合题目描述的二叉树个数...那么在更新出dp[n][k]值时就枚举下两边的点数和层数情况..每次两边都是种数相乘..最后之和为dp[n][k]的值..这里能取个巧..就是存在大量的左右换一下是同种情况的数..那么可以枚举一边的个数~~再乘2...但这样也要注意在两边同为k-1层时会多计数..所以当两边都为k-1层的情况不能乘2...

Program:

/* ID: zzyzzy12 LANG: C++ TASK: nocows */ #include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<queue> using namespace std; int n,k; int find(int n,int k) { int dp[205][105],sum,i,j,p,t; memset(dp,0,sizeof(dp)); dp[1][1]=1; for (i=3;i<=n;i+=2) for (j=(int)log2(i)+1;j<i;j++) { for (p=j*2-3;p<i;p+=2) { sum=0; for (t=1;t<j-1;t++) sum+=dp[i-p-1][t]; sum%=9901; dp[i][j]=(dp[i][j]+dp[p][j-1]*sum*2)%9901; dp[i][j]=(dp[i][j]+dp[p][j-1]*dp[i-p-1][j-1])%9901; } } return dp[n][k]; } int main() { freopen("nocows.in","r",stdin); freopen("nocows.out","w",stdout); scanf("%d%d",&n,&k); printf("%d\n",find(n,k)); return 0; }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值