[USACO][DP]Cow pedigrees

二叉树dp,一般两种分类思路:

1、分层
2、分左右子树

这种分类方法是不是很熟悉?对,我们遍历二叉树也是这样的思路。这里我使用了分左右子树行态进行讨论的方法来递归。

根据题目,记拥有k个层、n个节点的所求树有(k,n)种行态。那么只有2*K-1 <=N && N <= upper[K]-1且N为奇数的时候有解。
画一画基本情况:
(1,1) = 1
(2,3) = 1
(3,5) = 2; (3,7) = 1
研究第四层,可以发觉 (4,7)分左右子树可以看成(4,6+1),那么只要把6分出去、并且保证分完还是4层就可以;要保持4层,一个分出去的就必须是(3,?)。于是得到递推式:

(k,n) = (k,n-1 + 1) = sum_t (k-1,m) + (t, n - 1 -ml)

其中m为[2*(k-1) - 1, 2^{k-1}-1]中的奇数,t为所在数对拥有第二坐标为n-1-m的任何第一坐标。

题目要取模,别忘了取模。

用数组存然后如上递推的话,需要四层循环:一层是递推给k的,二层是给k对应n的,三层是找l,四层是找m。

这里关于循环上界,并不需要算pow(2,*),因为我们要求的N是给出的,而需要的第二维数字不需要比N大,所以构造循环。关键代码如下:

 for(int k = 4;k <= K;k ++)
    {
        for(int n = 2*k - 1;n <=N ;n += 2)
        {
            for(int m = 2*(k-1) - 1;m<=n-2; m +=2)
            {
                for(int t = 1;t <=k-1;t ++)
                {
                    if(a[t][n-1-m]!=0)
                    {
                        if(t != k - 1)
                            a[k][n] += a[k-1][m]*a[t][n-1-m]*2%MODULO;
                        else
                            a[k][n] += a[k-1][m]*a[t][n-1-m]%MODULO;
                    }
                }
            }
            a[k][n] = a[k][n]%MODULO;
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值