Combinatorics——HDUOJ 1799 - 迴圈多少次?(楊輝三角 - 排列組合)
阿新 • • 發佈:2018-11-09
原題:
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
3
3
解題思路:
楊輝三角 重要概念:
- 第n行數字和為2^(n-1)。
- 第n行的m個數可表示為C(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]);
}
}