1. 程式人生 > >【NOIP2016】組合數問題

【NOIP2016】組合數問題

本題在洛谷上的連結:https://www.luogu.org/problemnew/show/P2822


 

就在十一假期某學堂裡有幸聽出題人zhx大神講課。。。

都說是水題,但還是需要技巧滴。首先得知道組合數的那個在楊輝三角里體現得淋漓盡致的性質:c[n][m]=c[n-1][m-1]+c[n-1][m]。

考慮到多組資料,但k是一定的,可以再開個陣列來存到(i,j)時在第i行前j個的答案數,然後對應查詢累加即可。

本以為這樣就能過的,可是隻有55分?輸出中間結果一看,溢位了。。。

優化一下,判斷是否能被k整除時,直接c[i][j]%=k就好,若是0則令答案數加1。

 1 #include <cstdio>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 const int mmax = 2005, maxt = 1e4 + 5;
 7 
 8 int in[maxt], im[maxt], tri[mmax][mmax], ans[mmax][mmax];
 9 
10 int main() {
11     int t, k, maxn = 0;
12     scanf("%d%d", &t, &k);
13     for
(int i = 1; i <= t; ++i) { 14 scanf("%d%d", &in[i], &im[i]); 15 maxn = max(maxn, in[i]); 16 } 17 for (int i = 0; i <= maxn; ++i) 18 for (int j = 0; j <= i; ++j) { 19 if (!j || j == i) { 20 tri[i][j] = 1; 21 if
(j == i) ans[i][j] = ans[i][j - 1]; 22 } 23 else { 24 tri[i][j] = (tri[i - 1][j - 1] + tri[i - 1][j]) % k; 25 if (!tri[i][j]) ans[i][j] = ans[i][j - 1] + 1; 26 else ans[i][j] = ans[i][j - 1]; 27 } 28 } 29 for (int i = 1; i <= t; ++i) { 30 int out = 0; 31 for (int j = 0; j <= in[i]; ++j) 32 if (j <= im[i]) out += ans[j][j]; 33 else out += ans[j][im[i]]; 34 printf("%d\n", out); 35 } 36 return 0; 37 }
AC程式碼