class Choose { /* Recursively computes the binomial coefficient C(n,k) according to definition. * Precondition: 0 <= k <= n */ static long rchoose(int n, int k) { if (k == 0 || k == n) return 1; return rchoose(n-1, k-1) + rchoose(n-1, k); } /////////////////////////////////////////////////////////////////////////////////// /* * Computes choose(n, k) using bottom-up Dynamic Programming. * Table filling is row-by-row */ static long dpchoose_row(int n, int k) { long[][] table = new long[n+1][k+1]; for (int i = 0; i <= n; i++) { for (int j = 0; j <= Math.min(i,k); j++) { if (i == j || j == 0) table[i][j] = 1; else table[i][j] = table[i-1][j-1] + table[i-1][j]; } } return table[n][k]; } /////////////////////////////////////////////////////////////////////////////////// /* * Computes choose(n, k) using bottom-up Dynamic Programming. * Table filling is column-by-column */ static long dpchoose_col(int n, int k) { long[][] table = new long[n+1][k+1]; for (int j = 0; j <= k; j++) { for (int i = j; i <= n; i++) { if (i == j || j == 0) table[i][j] = 1; else table[i][j] = table[i-1][j-1] + table[i-1][j]; } } return table[n][k]; } /////////////////////////////////////////////////////////////////////////////////// // Any value that's impossible for a binomial coefficient will do. static final long UNKNOWN = -1; /* Precondition: n >= 0 and 0 <= k <= n * Computes C(n,k) using Memoization. */ static long mchoose(int n, int k) { // Creates the table and fills it with UNKNOWN. long[][] table = new long[n+1][k+1]; for (int i = 0; i <= n; i++) for (int j = 0; j <= k; j++) table[i][j] = UNKNOWN; // Computes C(n,k) using the recurrence & the table. return memoize(n, k, table); } /* Precondition: n >= 0 and 0 <= k <= n */ static long memoize(int n, int k, long[][] table) { if (table[n][k] == UNKNOWN) { if (k == 0 || n == k) { table[n][k] = 1; } else { table[n][k] = memoize(n-1, k, table) + memoize(n-1, k-1, table); } } return table[n][k]; } public static void main(String[] args) { int n = 56, k = 23; // System.out.printf("rchoose(%d, %d) = %d%n", n, k, rchoose(n, k)); System.out.printf("dpchoose_row(%d, %d) = %d%n", n, k, dpchoose_row(n, k)); System.out.printf("dpchoose_col(%d, %d) = %d%n", n, k, dpchoose_col(n, k)); System.out.printf("mchoose(%d, %d) = %d%n", n, k, mchoose(n, k)); } }