acdream 1412 2-3 Trees dp

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


發佈了109 篇原創文章 · 獲贊 5 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章