题目:点击打开链接
题意:构造一棵树,这棵树的每一层中的节点所拥有的子节点数相等,问有多少种构造方法。
思路:对称性。根据题意,可以想到,把这棵树从中间劈开,两边一定是对称的,继续劈开左右两边的子树,依然对称。用a[i]表示节点数为 i 的树的构造方法数,a[j]表示节点数为 j 的树的构造方法数,其中 j < i ,则若(i-1)%j==0,也就是 i 个节点去掉根后的 i-1 个节点能整除 j ,则节点数为 i 的树的可以由节点数 j 的已构造好的树作为 i 的子树构造,即a[i]=(a[i]+a[j])%mod。
代码:
#include <bits//stdc++.h>
using namespace std;
const int mod=1e9+7;
int main()
{
int n,a[1010];
memset(a,0,sizeof(a));
a[1]=1;
for(int i=2;i<=1000;i++)
{
for(int j=1;j<i;j++)
if((i-1)%j==0)
a[i]=(a[i]+a[j])%mod;
}
int cas=1;
while(~scanf("%d",&n))
{
printf("Case %d: %d\n",cas++,a[n]);
}
return 0;
}