1. 程式人生 > >usaco-Cow Pedigrees

usaco-Cow Pedigrees

none 狀態 class () 二叉 efi fin 分享圖片 條件

題意:

求出n個節點可以構成多少種高為h的二叉樹。
分析:

設左子樹節點數x,右子樹節點數為n-x-1,函數dp表示滿足條件的樹的個數,則dp(n)=dp(x)*(n-x-1)。

對於未知數h,dp[n]=∑dp[x]*dp[n-x-1],(x<=n-2,x in [1,3,5,…])。

故設dp[i][j]表示高不大於i,節點數為j的子樹個數。易得狀態轉移方程為:dp[i][j]=∑dp[i-1][k]*dp[i-1][j-k-1],(k in [1,3,5,…,j-2]),其中,邊界條件:dp[i][1]=1,顯然結果為dp[h][n]-dp[h-1][n]。

技術分享圖片
#include <iostream>
#include 
<string> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <vector> #include <queue> #define range(i,a,b) for(int i=a;i<=b;++i) #define LL long long #define rerange(i,a,b) for(int i=a;i>=b;--i) #define fill(arr,tmp) memset(arr,tmp,sizeof(arr)) using
namespace std; int n,h,dp[205][205]; void init(){ cin>>n>>h; fill(dp,0); range(i,1,h)dp[i][1]=1; } void solve(){ range(i,1,h) range(j,3,n) { range(k, 1, j - 2) { dp[i][j]=(dp[i][j]+dp[i-1][k]*dp[i-1][j-k-1]%9901)%9901; ++k; }
++j; } cout<<(dp[h][n]-dp[h-1][n]+9901)%9901<<endl; } int main() { init(); solve(); return 0; }
View Code

usaco-Cow Pedigrees