一棵k層的二叉樹,含有n個結點,每一個結點可能有0或者2個孩子,求全部可能的二叉樹結構數對9901取餘的結果。剛開始想到動態規劃,可是沒想出好的動態轉移方程,後來想搜索,複雜度過高。無奈看告終題報告。ios
dp[i][j]表示i個結點能夠組成的不超過j層的不一樣二叉樹的數量。一共i個結點,除了根結點,還有i-1個結點,左子樹m個結點,右子樹i-1-m個結點,左子樹不超過j-1層的數量dp[m][j-1],右子樹不超過j-1層的數量dp[i-1-m][j-1],所以dp[i][j]=dp[m][j-1]*dp[i-1-m][j-1],又由於m的取值爲1,2,…,i-2,因此dp[i][j]= dp[1][j-1]*dp[i-2][j-1]+dp[2][j-1]*dp[i-3][j-1]+...+dp[i-2][j-1]*dp[1][j-1],即dp[i][j]=∑(dp[m][j-1]*dp[i-1-m][j-1])(m=1,2…,i-2)。web
/* ID: jzzlee1 PROG:nocows LANG:C++ */ //#include<iostream> #include<fstream> using namespace std; ifstream cin("nocows.in"); ofstream cout("nocows.out"); int dp[210][110]; int main() { int n,k; cin>>n>>k; int i,j,m; for(j=0;j<=k;j++)//設置邊界條件 dp[1][j]=1; for(j=2;j<=k;++j) for(i=2;i<=n;++i) for(m=1;m<=i-1;++m) dp[i][j]=(dp[i][j]+dp[m][j-1]*dp[i-1-m][j-1])%9901;//遞歸求解 cout<<(dp[n][k]-dp[n][k-1]+9901)%9901<<endl; return 0; }