题目链接:acdream 1412
有一种树满足,除叶子节点以外所有点的孩纸数要么是2,要么是3。且所有叶子节点处于同一个深度。问有l个叶子节点的树多少种构成方案。
我们用dp[i]表示有i个叶子节点的树的构成情况,在这i个叶子节点上接2~3个节点就会对dp[2*i]~dp[3*i]有贡献。因此对每个i计算对2*i~3*i的贡献。
转移方程dp[i*2+j]+=dp[i]*C(j,i) (0<=j<=i) C(j,i)为组合数
/******************************************************
* File Name: j.cpp
* Author: kojimai
* Creater Time:2014年10月02日 星期四 12时51分34秒
******************************************************/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
#define FFF 5005
long long a[FFF];
long long c[2505][2505];
long long cc(int x,int y,int r)
{
if(x==y||y==0||x==0)
{
c[x][y] = 1;
return 1;
}
if(x&&y)
{
c[x][y] = c[x-1][y-1] + c[x-1][y];
c[x][y] %= r;
return c[x][y];
}
}
int main()
{
int l,r;
while(~scanf("%d%d",&l,&r))
{
memset(a,0,sizeof(a));
a[1]=1;
for(int i=1;i<=l/2;i++)
{
long long tmp = 1;
for(int j=0;j<=i&&j+2*i<=l;j++)
{
tmp = cc(i,j,r);
if(2*i+j>l)
break;
a[i*2+j]+=(a[i] * tmp)%r;
a[i*2+j]%=r;
}
}
cout<<a[l]%r<<endl;
}
return 0;
}