POJ 1306 Combinations 递推 || 暴力
2016-07-28 20:25
477 查看
【POJ】1306 Combinations
解法一:
Cnm=m!n!(m−n)!
但是此题取值范围是 100 暴力的话肯定会爆掉;
于是我们可以进行约分;
由于n<=m;
所以分子分母同时除以 ∑ni=1i
原式变为 m−n+1∗m−n+2∗m−n+3…∗m(m−n)!
为了更大程度的防止boom;
我们采取边乘边除的方式;
代码:
解法二:
递推。
根据组合数的递推式 Cmn=Cmn−1+Cm−1n−1
可以用类似 dp的方法递推。
代码:
解法一:
Cnm=m!n!(m−n)!
但是此题取值范围是 100 暴力的话肯定会爆掉;
于是我们可以进行约分;
由于n<=m;
所以分子分母同时除以 ∑ni=1i
原式变为 m−n+1∗m−n+2∗m−n+3…∗m(m−n)!
为了更大程度的防止boom;
我们采取边乘边除的方式;
代码:
#include <iostream> #include <queue> #include <cstring> #include <cstdio> using namespace std; int n, m; int main() { while (cin >> n >> m && n && m) { long long ans = 1; int j = 1; for(int i = n-m+1; i <= n; i ++) { ans *= i; while(ans % j == 0 && j <= m) { ans /= j; j ++; } } printf("%d things taken %d at a time is %I64d exactly.\n",n,m,ans); } return 0; }
解法二:
递推。
根据组合数的递推式 Cmn=Cmn−1+Cm−1n−1
可以用类似 dp的方法递推。
代码:
#include <iostream> #include <queue> #include <cstdio> #include <queue> using namespace std; const int MAXN = 100 + 10; long long c[MAXN][MAXN]; int main() { int n, m; for(int i = 0; i < MAXN; i ++) c[i][0] = 1; for(int i = 1; i < MAXN; i ++) for(int j = 1; j < MAXN; j ++) c[i][j] = c[i-1][j] + c[i-1][j-1]; while(scanf("%d%d",&n,&m) && n && m) printf("%d things taken %d at a time is %lld exactly.\n",n,m,c [m]); return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2159 Ancient Cipher
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- [数论]poj2635__The Embarrassed Cryptographer
- [二分图匹配]poj2446__Chessboard
- POJ1050 最大子矩阵和
- 用单调栈解决最大连续矩形面积问题