題目鏈接: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;
}