USACO2.32 Cow Pedigrees

题意:

用N个点组成一棵深度为K的二叉树,求一共有几种方法?

分析:哎,感觉自己好水呀,借鉴了USACO上面的题解才过的,自己想了好久都没什么思路

设dp[i,j]表示用i个点组成深度最多为j的二叉树的方法数,(注意,这里i必定是奇数),则:

dp[i,j]=∑(dp[k,j-1]×dp[i-1-k,j-1])(k∈{1..i-2})
边界条件:dp[1,i]=1

我们要求的是深度恰好为K的方法数S,易知S=dp[n,k]-dp[n,k-1]。但需要注意的是,如果每次都取模,最后可能会有dp[n,k]<dp[n,k-1],所以可以用S=(dp[n,k]-dp[n,k-1]+v) mod v

/*
ID: nanke691
LANG: C++
TASK: nocows
*/
#include<iostream>
#include<algorithm>
#include<fstream>
#include<string.h>
using namespace std;
int dp[210][110];
int main()
{
	freopen("nocows.in","r",stdin);
	freopen("nocows.out","w",stdout);
	int n,k;
	cin>>n>>k;
	memset(dp,0,sizeof(dp));
	for(int i=1;i<=n;i++)
		dp[1][i]=1;
	for(int i=3;i<=n;i+=2)
		for(int j=2;j<=k;j++)
		{
			for(int l=1;l<=i-2;l+=2)
				dp[i][j]+=(dp[l][j-1]*dp[i-l-1][j-1])%9901;
			dp[i][j]%=9901;
		}
	cout<<(dp[n][k]-dp[n][k-1]+9901)%9901<<endl;
	return 0;
}

 

posted @ 2011-11-15 00:45  枕边梦  阅读(217)  评论(0编辑  收藏  举报