zoukankan      html  css  js  c++  java
  • POJ1430 Binary Stirling Numbers 组合数学

    这题是定义如下的一个数:

    S(0, 0) = 1; S(n, 0) = 0 for n > 0;S(0, m) = 0 for m > 0;

    S(n, m) = m S(n - 1, m) + S(n - 1, m - 1), for n, m > 0.

    也就是题中所说的把一个含有n个元素的集合分成m份,共有多少种分法。

    现在题目就是要求S(n, m)的奇偶性。

    如果m是一个偶数的话,那么我们可以推出 S(n, m) Ξ S(n-1, m-1) (mod 2),如果m是一个奇数的话,我们推出S(n, m) Ξ (S(n-1, m) + S(n-1, m-1)) (mod 2)。后面看到某一大牛所说的利用画图来推导这个表达式,整了一下,S(n, m)这个状态可由左边的S(n-1, m) 以及 斜下方的 S(n-2, m-2)得到。最后得到结果是c( n-m, n-m+(m-1)/2 ).

    最后只要确定一个组合数是否为奇数即可,c(A, B) = B! / (A! * (B-A)!) 我们通过提取上下阶乘的2的个数即可,因为这个式子一定能够约分成整数,那么只要2这个因子没有就一定是一个奇数了。

    代码如下:

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    using namespace std;
    
    int s[1002][1002];
    
    void pre()
    {
        s[0][0] = 1;
        for (int i = 0; i <= 50; ++i) { 
            for (int j = 0; j <= 50; ++j) {
                if (!i && !j) continue;
                else if (!i || !j) s[i][j] = 0; 
                else s[i][j] = j * s[i-1][j] + s[i-1][j-1];
            }
        }    
        for (int i = 0; i <= 10; ++i) {
            for (int j = 0; j <= 10; ++j) { 
                printf("s[%d][%d]= %d\n", i, j, s[i][j]); 
            }
            puts("");
        }
        
        
        
    }
    
    int main()
    {
    //    pre();
        int T, n, m, t1, t2;
        scanf("%d", &T);
        while (T--) {
            t1 = t2 = 0;
            scanf("%d %d", &n, &m);
            if (m == 0 && n) {
                puts("0");
                continue;    
            }
            n -= m;
            m = n + (m-1)/2; // n此处就是n-m了
            int A = n, B = m, C = (B-A);
            while (B) {
                t1 += B/2;
                B /= 2;
            }
            while (A) {
                t2 += A/2;
                A /= 2;    
            }
            while (C) {
                t2 += C/2;
                C /= 2;    
            }
            if (t1 == t2) {
                puts("1");    
            }
            else {
                puts("0");
            }
        }
        return 0;
    }




  • 相关阅读:
    java进程自动杀死
    线程池的取值(一)与拒绝策略
    zju 1383 Binary Numbers
    可以连续几行数,,,分别相加求和
    几个数字的和
    zju 2812 Quicksum---------hdu 2734
    rwkj 1332 C语言实验四(函数):题目1、数字根
    zju 1295 Reverse Text
    zju 1241 Geometry Made Simple
    hdu 1379 DNA Sorting
  • 原文地址:https://www.cnblogs.com/Lyush/p/2633168.html
Copyright © 2011-2022 走看看