题意:给你n 个点,构造一棵树,使得同一层结点的子节点个数相同,问能构建出多少个
重点思路:“同一层结点的子节点个数相同”,仔细想想这句话,就会发现,能满足这个关系的树,子树必定是对称的,也就是从根节点切开两部分,左子树依然是对称的,右子树也是对称的,不过这还不够,这个数的所有所以基于这点,我们可以想到,除开树根外,下面的子树(可能一棵子树,或者两棵,多棵),一定要完全相同的,为什么?哪怕每棵子树是对称的,但是子树与子树之间不同,那么都挂在树根上的时候,是不能满足 “使到同一层的节点所拥有的子节点数相等” 的。
有了这点,就可以及进行递推了,dp[i]=sum(dp[j]) (i-1)%j==0,,因为一个节点一定要用去做树根,所以剩下i-1个点,这i-1个节点把它分成几份,这几份完全相同,其本身强烈对称
代码:
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#define lson l,mid,num<<1
#define rson mid+1,r,num<<1|1
#define MOD 1000000007;
using namespace std;
long long dp[1010];
void DP()
{
memset(dp,0,sizeof(dp));
dp[1]=1;
dp[2]=1;
for(int i=3; i<=1000; i++)
for(int j=1; j<=i-1; j++)
if((i-1)%j == 0)
dp[i] = (dp[i]+dp[j])%MOD;
}
int main()
{
int n,g=1;
DP();
while(scanf("%d",&n)!=EOF)
{
printf("Case %d: %I64d\n",g++,dp[n]);
}
return 0;
}