1. 程式人生 > >Combinatorics——HDUOJ 1799 - 迴圈多少次?(楊輝三角 - 排列組合)

Combinatorics——HDUOJ 1799 - 迴圈多少次?(楊輝三角 - 排列組合)

原題


  • Problem Description

我們知道,在程式設計中,我們時常需要考慮到時間複雜度,特別是對於迴圈的部分。例如,
如果程式碼中出現
for( i=1; i<=n; i++) OP ;
那麼做了n次OP運算,如果程式碼中出現
for(i=1; i<=n; i++)
for(j=i+1; j<=n; j++) OP;
那麼做了n*(n-1)/2 次OP 操作
現在給你已知有m層for迴圈操作,且每次for中變數的起始值是上一個變數的起始值+1(第一個變數的起始值是1),終止值都是一個輸入的n,問最後OP有總共多少計算量。

  • Input

    有T組case,T<=10000。每個case有兩個整數m和n,0 < m <= 2000,0 < n <= 2000.

  • Output

    對於每個case,輸出一個值,表示總的計算量,也許這個數字很大,那麼你只需要輸出除1007留下的餘數即可。

  • Sample Input

    2
    1 3
    2 3

  • Sample Output

    3
    3

  • 解題思路:

    這裡寫圖片描述

    楊輝三角 重要概念:

    • n行數字和為2^(n-1)
    • 第n行的m個數可表示為C(n-1,m-1)
      ,即為從n-1個不同元素中取m-1個元素的組合數。
    • 第n行的第m個數和第n-m+1個數相等 ,為組合數性質之一。
    • 每個數字等於上一行的左右兩個數字之和。可用此性質寫出整個楊輝三角。即第n+1行的第i個數等於第n行的第i-1個數和第i個數之和,這也是組合數的性質之一。即 C(n+1, i) = C(n, i) + C(n, i-1)
    • 二項式定理:(a+b)^n的展開式中的各項係數依次對應楊輝三角的第(n+1)行中的每一項

    解題思路:

    這道題利用 排列組合Cn(m)(也就是從n個元素中任取m個元素)的思考方式,實現過程用楊輝三角。
    假設現在有4個 小球 A B C D 要從中取2個 用排列組合的方式:先取A 然後可以依次取 B C D ;接下來 取B 然後可以依次取C D ; 接下來取C ,但只能取剩下的D; 這樣就有3 + 2 + 1 = 6 種組合C( 4 , 2 ) = C( 3 , 1) + C( 3 , 2) = 3 + 3。
    這裡的4 就是題目的n, 這裡的2就是題目的m(迴圈次數);
    所以題目問的操作次數 也就是 問有多少種取球方式;

    程式碼:

    #include <cstdio>
    int result[2001][2001];
    void preprocessing()//預處理(楊輝三角)
    {
        for (int i = 0; i < 2001; i++)
            result[i][0] = result[i][i] = 1;
        for (int i = 2; i < 2001; i++)
            for (int j = 1; j < i; j++)
                result[i][j] = (result[i - 1][j] + result[i - 1][j - 1]) % 1007;
    }
    int main()
    {
        preprocessing();
        int T, m, n;
        scanf_s("%d", &T);
        while (T--)
        {
            scanf_s("%d%d", &m, &n);
            printf("%d\n", result[n][m]);
        }
    }