public class Choose { /* Computes 'n choose k' using its definition */ static long recChoose(int n, int k) { return (k==0 || k==n) ? 1 : recChoose(n-1, k-1) + recChoose(n-1, k); } ///////////////////////////////////////////////////////////////////////////// static long[][] dpTable; /* * Computes 'n choose k' using bottom-up dynamic programming. * Table-filling is row-by-row. */ static long dpChooseRow(int n, int k) { for (int i = 0; i <= n; i++) for (int j = 0; j <= Math.min(i, k); j++) dpTable[i][j] = (j==0 || j==i) ? 1 : dpTable[i-1][j] + dpTable[i-1][j-1]; return dpTable[n][k]; } /* * Computes 'n choose k' using bottom-up dynamic programming. * Table-filling is column-by-column. */ static long dpChooseColumn(int n, int k) { for (int j = 0; j <= k; j++) for (int i = j; i <= n; i++) dpTable[i][j] = (j==0 || j==i) ? 1 : dpTable[i-1][j] + dpTable[i-1][j-1]; return dpTable[n][k]; } static long[] array; /* * Computes 'n choose k' using bottom-up dynamic programming. * Table-filling is row-by-row, but we save space by using only 1D-array. */ static long dpChooseSpace(int n, int k) { for (int i = 0; i <= n; i++) for (int j = Math.min(i, k); j >= 0; j--) array[j] = (j==0 || j==i) ? 1 : array[j-1] + array[j]; return array[k]; } ///////////////////////////////////////////////////////////////////////////// static long[][] mzTable; static final long UNKNOWN = 0; /* * Computes 'n choose k' using memoization (a top-down approach). */ static long mzChoose(int n, int k) { if (mzTable[n][k] == UNKNOWN) { if (k == 0 || k == n) mzTable[n][k] = 1; else mzTable[n][k] = mzChoose(n-1,k) + mzChoose(n-1,k-1); } return mzTable[n][k]; } ///////////////////////////////////////////////////////////////////////////// public static void main(String[] args) { int n = Integer.parseInt(args[0]); int k = Integer.parseInt(args[1]); if (n < 0 || k < 0 || k > n) { System.err.println("invalid arguments"); System.exit(1); } long value; double time; Stopwatch sw1 = new Stopwatch(); value = recChoose(n, k); time = sw1.elapsedTime(); System.out.printf("%nrecChoose(%d, %d) = %d%n", n, k, value); System.out.printf("time spent: %.2f%n", time); mzTable = new long[n+1][k+1]; Stopwatch sw2 = new Stopwatch(); value = mzChoose(n, k); time = sw2.elapsedTime(); System.out.printf("%nmzChoose(%d, %d) = %d%n", n, k, value); System.out.printf("time spent: %.2f%n", time); dpTable = new long[n+1][k+1]; Stopwatch sw3 = new Stopwatch(); value = dpChooseRow(n, k); time = sw3.elapsedTime(); System.out.printf("%ndpChooseRow(%d, %d) = %d%n", n, k, value); System.out.printf("time spent: %.2f%n", time); dpTable = new long[n+1][k+1]; Stopwatch sw4 = new Stopwatch(); value = dpChooseColumn(n, k); time = sw4.elapsedTime(); System.out.printf("%ndpChooseColumn(%d, %d) = %d%n", n, k, value); System.out.printf("time spent: %.2f%n", time); array = new long[k+1]; Stopwatch sw5 = new Stopwatch(); value = dpChooseSpace(n, k); time = sw5.elapsedTime(); System.out.printf("%ndpChooseSpace(%d, %d) = %d%n", n, k, value); System.out.printf("time spent: %.2f%n%n", time); } }