【Python3】【树形dp】uva10253 Series-Parallel Networks

本文介绍了一种算法,用于计算具有特定结构的树的数量,其中每棵子树最多包含i个叶子节点,并且整棵树有n个叶子节点。通过递归地计算不同子树的组合数来解决这个问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设“共n个叶子,且每个非叶节点至少有两个子节点”的树的数量为f[n],再乘2就是本题答案。

设状态d(i,j)表示每棵子树最多包含i个叶子、一共有j个叶子的树的个数。于是f(n)=d(n-1,n)。假设恰好包含i个叶子的子树有p棵,那么这些树的组合数等于从f(i)棵树中选择p棵树的方案数,即C(f(i)+p-1,p),再去乘上剩下的(包含叶子树少于i的)子树的方案数d(i-1,j-p*i),因此d(i,j)=sum{C(f(i)+p-1,p)*d(i-1,j-p*i) | p>=0,p*i<=j}

边界是:i>=0时d(i,0) = 1,i>=1时d(i,1) = 1,但d(0,i) = 0。

def C(n, m):
    res = 1;
    for i in range(m):
        res *= (n-i);
    for i in range(1,m+1):
        res //= i;
    return res;

f = [0] + [1] + [0] * 33;
d = [([0] * 35) for i in range(35)];
n = 30;
for i in range(n+1):
    d[i][0]=1;
for i in range(1,n+1):
    d[i][1]=1;
    d[0][i]=0;
for i in range(1,n+1):
    for j in range(2,n+1):
        for p in range(0,j+1,i):
            d[i][j] += C(f[i]+p//i-1, p//i) * d[i-1][j-p];
    f[i+1] = d[i][i+1];
while(True):
    n=int(input());
    if(n==0):
        break;
    if(n==1):
        print(1);
    else:
        print(2*f[n]);

转载于:https://www.cnblogs.com/autsky-jadek/p/8842469.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值