题意:n 个点,构造一棵树,使得同一层结点的子节点个数相同,问能构建出多少种树。
分析:同一层结点的子节点个数相同,满足这个关系的树,子树必定是对称的,从根节点切开,左子树依然是对称的,右子树也是对称的,除开树根外,下面的子树(可能一棵子树,或者两棵,多棵),一定要完全相同,哪怕每棵子树是对称的,但是子树与子树之间不同,那么都挂在树根上的时候,是不能满足使到同一层的节点所拥有的子节点数相等的。
dp[i]=sum(dp[j]) (i-1)%j==0,,一个节点要用去做树根,所以剩下i-1个点,这i-1个节点把它分成几份,这几份完全相同,其本身强烈对称。
dp[i]表示有i个节点的满足要求的方案数。
#include<iostream> using namespace std; #define N 1010 #define MOD (int(1e9)+7) int dp[N]; //dp[i]代表有i个人时有多少种情况 void DP() { int i,j; memset(dp,0,sizeof(dp)); dp[1]=dp[2]=1; for(i=3;i<=1001;i++) for(j=1;j<=i-1;j++) if((i-1)%j==0) //每次都要除去首领(i-1),每一层拥有的子树数目是相同的 dp[i]=(dp[i]+dp[j])%MOD; } int main() { int n,t=0; DP(); while(scanf("%d",&n)==1) { printf("Case %d: %d\n",++t,dp[n]); } return 0; }
原文地址:http://blog.csdn.net/a809146548/article/details/46419375