競技プログラミングの問題を解く際、組み合わせ(nCr)、順列(nPr)、階乗(n!) の計算を行うことがちょくちょくあるので、今後の時短のため以下のメソッドを作成した。
// nCr を計算する。 // 計算結果は int max を超えやすいので long 型としている。 // long 型を超えそうな場合は BigInteger を使用する。 long calcCombination(int n, int r) { if (n < 0 || r < 0) { throw new IllegalArgumentException("Arguments must be 0 and over."); } else if (n == r || r == 0) { return 1; } else if (n < r) { return 0; } else { long result = 1; for (int i = 1; i <= r; i++) { result = result * (n - i + 1) / i; } return result; } } // nPr を計算する。 long calcPermutation(int n, int r) { if (n < 0 || r < 0) { throw new IllegalArgumentException("Arguments must be 0 and over."); } else if (r == 0) { return 1; } else if (n < r) { return 0; } else { long result = 1; for (int i = 1; i <= r; i++) { result = result * (n - i + 1); } return result; } } // n! を計算する。 long calcFactorial(int n) { if (n < 0) { throw new IllegalArgumentException("Argument must be 0 and over."); } else { long result = 1; for (int i = n; i >= 1; i--) { result = result * i; } return result; } }
上記では、nC0 や nP0 の計算結果は 1 としている。これは、ネットでいろいろ調べたところ、「何も選ばない」という1通りがあるという解釈になるそうなのでそうした。また、0Cr や 0Pr (r ≠ 0) については、選ぶ方法がないので計算結果は 0 としている。