NOIP 2016 Senior 4 - 组合数问题
2017-07-27 16:29
288 查看
这道题。。。其实我第一反应是爆搜。由于组合数的计算有多种公式,思路往往会禁锢,这不,题目故意把公式给了你,让你往这个公式上去想,不超时才怪。。。
在使用该公式进行单行递推时,能够轻松地通过一个点,但是对于10000组测试数据就无能为力了,同时,这种方法还受溢出的限制,因此不可取。如果用这种方法应该能得到60分。
正确的做法应该是使用递推公式。因为递推公式是加法,而通项公式是乘法和除法。加法让求余有了可能。观察发现,题目要求在一开始就输入k,而不是每组数据一个,这更坚定了使用递推公式提前初始化好的信心。
再看数据,发现2000的规模是允许我们以O(n2)的时间复杂度进行初始化的。我们必须要做到查询的时间复杂度降到O(1),才能让初始化有意义(2000*2000也不小了)。
首先我们来看看如何判断一个组合数是不是k的倍数。很简单,模k后判断是否为0即可。接下来就是查询,这时我们应该很自然地想到了二维和数组,到这里这道题就简单了。记住用之前写的暴力多测试几下!!!= =
参考代码(稍慢,可以根据题目给的n,m的最大值进行优化,还可以把long long改成int,因为懒所以我就不改了)
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <string> #include <stack> #include <queue> #include <deque> #include <map> #include <set> #include <bitset> using std::cin; using std::cout; using std::endl; typedef unsigned long long INT; inline INT readIn() { INT a = 0; bool minus = false; char ch = getchar(); while(!(ch == '-' || ch >= '0' && ch <= '9')) ch = getchar(); if(ch == '-') { minus = true; ch = getchar(); } while(ch >= '0' && ch <= '9') { a *= 10; a += ch; a -= '0'; ch = getchar(); } if(minus) a = -a; return a; } const INT maxn = 2005; INT mod; INT n, m; INT C[maxn + 5][maxn + 5]; INT f[maxn + 5][maxn + 5]; void run() { INT a = readIn(); mod = readIn(); for(int i = 1; i <= maxn; i++) { C[i][0] = C[i][i] = 1; for(int j = 1; j < i; j++) { C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod; } } for(int i = 1; i <= maxn; i++) { for(int j = 0; j <= maxn; j++) { if(j) { f[i][j] = f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1] + (j <= i && !C[i][j]); } else { f[i][j] = f[i - 1][j] + (j <= i && !C[i][j]); } } } while(a--) { INT ans = 0; n = readIn(); m = readIn(); cout << f [m] << endl; } } int main() { run(); return 0; }
4000
相关文章推荐
- 【NOIP2016】 组合数问题
- [noip2016]组合数问题 题解
- 【noip 2016】组合数问题
- NOIP2016 提高组Day2 T1 组合数问题
- CJOJ 2255 【NOIP2016】组合数问题 / Luogu 2822 组合数问题 (递推)
- [NOIp2016提高组]组合数问题
- 【NOIP 2016】 组合数问题 解题报告
- Noip2016 组合数问题
- NOIP 2016 提高组 复赛 Day2T1==洛谷2822 组合数问题
- 【NOIP2016】洛谷2282 组合数问题
- NOIP 2016 提高组 Day2 组合数问题
- 【jzoj4906】【NOIP2016提高组】【组合数问题】【数论】
- 洛谷 2822 [NOIP2016] 组合数问题 递推
- [NOIP2016真题]组合数问题
- [NOIP提高组2016第一题]组合数问题
- LuoguP2822[NOIP2016] 组合数问题 解题报告【组合数取模+矩阵前缀和】
- 【NOIP 2016 day2 T1 T2】组合数问题,蚯蚓——题解
- 2559. [NOIP2016]组合数问题
- NOIP2016 day2T1 组合数问题
- NOIP2016 组合数问题