import java.util.Arrays; import java.util.Vector; public class ElectoralCounts { public static void main(String[] args) { // TODO Auto-generated method stub int[] votes = { 9, 3, 11, 6, 55, 9, 7, 3, 3, 29, 16, 4, 4, 20, 11, 6, 6, 8, 8, 4, 10, 11, 16, 10, 6, 10, 3, 5, 6, 4, 14, 5, 29, 15, 3, 18, 7, 7, 20, 4, 9, 3, 11, 38, 6, 3, 13, 12, 5, 10, 3 }; int sum = 0; for (int i = 0; i < votes.length; i++) { sum += votes[i]; } calculateMaxSum(votes, sum / 2); } public static void calculateMaxSum(int[] votes, int sum) { int[][] M = new int[votes.length + 1][sum + 1]; numSolutions = new long[votes.length + 1][sum + 1]; resetNumSolutions(); for (int i = 1; i <= votes.length; i++) { int w_i = votes[i - 1]; for (int w = 0; w <= sum; w++) { if (w < w_i) { M[i][w] = M[i - 1][w]; } else { int choiceAddElement = votes[i - 1] + M[i - 1][w - w_i]; int choiceIgnoreElement = M[i - 1][w]; if (choiceAddElement > choiceIgnoreElement) { M[i][w] = choiceAddElement; } else { M[i][w] = choiceIgnoreElement; } } } } // M[votes.length][sum] = 269 PathCount(M, votes, votes.length, sum); System.out.println(M[votes.length][sum]); System.out.println("Num Solutions: " + numSolutions[votes.length][sum]); System.out.println(bad_items); // printOptArray(M); // printNumSolutionsArray(); } private static long path_count = 0; private static long bad_items = 0; private static Vector<Integer> soln = new Vector<Integer>(); private static long[][] numSolutions; public static long PathCount(int[][] M, int[] votes, int i, int j) { if (i < 0 || j < 0) { bad_items++; return 0; } if (numSolutions[i][j] != -1) { return numSolutions[i][j]; } if (i == 0 && j == 0) { // printOutSolution(); path_count++; return 1; } else { int w = j; int w_i = votes[i - 1]; if (w < w_i) { M[i][w] = M[i - 1][w]; numSolutions[i][j] = PathCount(M, votes, i - 1, w); } else { int choiceAddElement = votes[i - 1] + M[i - 1][w - w_i]; int choiceIgnoreElement = M[i - 1][w]; if (choiceAddElement == choiceIgnoreElement) { numSolutions[i][j] = PathCount(M, votes, i - 1, w); soln.add(w_i); numSolutions[i][j] += PathCount(M, votes, i - 1, w - w_i); soln.removeElement(w_i); } else { if (choiceAddElement > choiceIgnoreElement) { M[i][w] = choiceAddElement; soln.add(w_i); numSolutions[i][j] = PathCount(M, votes, i - 1, w - w_i); soln.removeElement(w_i); } else { M[i][w] = choiceIgnoreElement; numSolutions[i][j] = PathCount(M, votes, i - 1, w); } } } return numSolutions[i][j]; } } private static void printOutSolution() { int sum = 0; for (int k = 0; k < soln.size(); k++) { sum += soln.elementAt(k); } Object[] solnArray = soln.toArray(); // Arrays.sort(solnArray); System.out.println(sum + ": " + Arrays.toString(solnArray)); // soln.clear(); } private static void printOptArray(int[][] M) { for (int i = 0; i < M.length; i++) { System.out.println(""); for (int j = 0; j < M[i].length; j++) { System.out.print(M[i][j] + " "); } } } private static void printNumSolutionsArray() { for (int i = 0; i < numSolutions.length; i++) { System.out.println(""); for (int j = 0; j < numSolutions[i].length; j++) { System.out.print(numSolutions[i][j] + " "); } } } private static void resetNumSolutions() { for (int i = 0; i < numSolutions.length; i++) { for (int j = 0; j < numSolutions[i].length; j++) { numSolutions[i][j] = -1; } } } }