zoukankan      html  css  js  c++  java
  • UVa 10253 (组合数 递推) Series-Parallel Networks

    《训练之南》上的例题难度真心不小,勉强能看懂解析,其思路实在是意想不到。

    题目虽然说得千奇百怪,但最终还是要转化成我们熟悉的东西。

    经过书上的神分析,最终将所求变为:

    共n个叶子,每个非叶节点至少有两个子节点的 树的个数f(n)。最终输出2 × f(n)

    首先可以枚举一下根节点的子树的叶子个数,对于有i个叶子的子树,共有f(i)种,

    设d(i, j)表示每棵子树最多有i个叶节点,一共有j个叶节点的方案数。

    所求答案为d(n-1, n)

    假设恰好有i个叶子的子树有p棵,因为每个子树互相独立,所以对于p个有i个叶子的子树,共有C(f(i)+p-1, p)种情况,重复元素的全排列。

    d(i, j) = sum{C(f(i)+p-1, p) × d(i-1, j-p×i) | p >= 0 且 p×i <= j }

    边界:

    d(i, 0) = d(i, 1) = 1 (i >= 1), d(0, 0) = 1

     1 #include <cstdio>
     2 
     3 const int maxn = 30;
     4 long long d[31][31], f[31];
     5 
     6 long long C(long long n, long long m)
     7 {
     8     long long ans = 1;
     9     if(m > n - m) m = n - m;
    10     for(int i = 0; i < m; i++)
    11     {
    12         ans *= n - i;
    13         ans /= i+1;
    14     }
    15     return ans;
    16 }
    17 
    18 int main()
    19 {
    20     f[1] = 1;
    21     int n = maxn;
    22     d[0][0] = 1;
    23     for(int i = 1; i <= n; i++) d[i][0] = d[i][1] = 1;
    24     for(int i = 1; i <= n; i++)
    25     {
    26         for(int j = 2; j <= n; j++)
    27         {
    28             for(int p = 0; p * i <= j; p++)
    29                 d[i][j] += C(f[i]+p-1, p) * d[i-1][j-p*i];
    30         }
    31         f[i+1] = d[i][i+1];
    32     }
    33 
    34     while(scanf("%d", &n) == 1 && n)
    35         printf("%lld
    ", n == 1 ? 1 : f[n] * 2);
    36 
    37     return 0;
    38 }
    代码君
  • 相关阅读:
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4319920.html
Copyright © 2011-2022 走看看