HDU 4472 Count

来源:互联网 发布:单片机复位电路的作用 编辑:程序博客网 时间:2024/05/16 00:26

题目

题目大意 :给n个点构成一棵树,要求每层的每个节点的子节点数目相同


题目分析 :用dp[i]表示节点个数为i的方法数,一个节点作为根的时候剩下的i-1个节点进行均分,分成j份所以当(i-1) % j == 0时 dp[i] += dp[j],
这就是这道题的动规方程。最后注意取模

给n个节点,构建一棵树,使到同一层的节点所拥有的子节点数相等,问能构建出多少个
这句话,“使到同一层的节点所拥有的子节点数相等”,并没有把话说得很白,但是细想就可以发现,这句话是等同于说,这棵树是对称,而且非常对称,甚至可以想象到,以树根为轴,把树劈成两份,两边是对称的,取其中一边,再以树根劈开,两边还是对称的(这样强的对称性才满足题目说的那句话)
所以基于这点,我们可以想到,除开树根外,下面的子树(可能一棵子树,或者两棵,多棵),一定要完全相同的,为什么?哪怕每棵子树是对称的,但是子树与子树之间不同,那么都挂在树根上的时候,是不能满足  “使到同一层的节点所拥有的子节点数相等” 的。

因而问题来到这里就比较明显了,就是要找出一棵或多颗完全相同的,而且其本身也是强烈对称的子树,这不就是一个完全相同的子问题吗?因而递推就派上用场了
dp[i]=sum{ dp[j] } ( (i-1)%j==0 )  ,因为一个节点一定要用去做树根,所以剩下i-1个点,这i-1个节点把它分成几份,这几份完全相同,其本身强烈对称
总结:这题的英文本身也不好理解,能理解出中文的这句话“使到同一层的节点所拥有的子节点数相等” 是不容易的,能想到是由多颗完全相同的且其本身也完全对称的也不容易。当理解到这里,写代码已经是很容易的事情。

代码:

#include <cstdio>int const MAX = 1e3 + 5;int const MOD = 1e9 + 7;int dp[MAX];int main(){    dp[1] = 1;    for(int i = 1; i <= 1000; i++)        for(int j = 1; j < i; j++)            if((i - 1) % j == 0)                dp[i] += dp[j] % MOD;    int n, ca = 1;    while(scanf("%d", &n) != EOF)        printf("Case %d: %d\n", ca++, dp[n] % MOD);}


0 0
原创粉丝点击