A presidential candidate could be elected with as a little as 21.8% of the popular vote by getting just over 50% of the votes in DC and each of 39 small states. This is true even when everyone votes and there are only two candidates. In other words, a candidate could lose with 78.2% of the popular vote by getting just under 50% in small states and 100% in large states.

The optimal set of states to take (the one that lets a candidate win with the smallest popular vote) is not the N states with the smallest population. It's also not the N states with the smallest value for (population/electors), which would be optimal if you could get exactly 270 electoral votes that way.

The optimal solution happens to get exactly 270 electoral votes. In this solution, the winner takes DC, the 37 smallest states, the 39th smallest state, and the 40th smallest state. (The winner takes Alabama, Alaska, Arizona, Arkansas, Colorado, Connecticut, Delaware, DC, Hawaii, Idaho, Indiana, Iowa, Kansas, Kentucky, Louisiana, Maine, Maryland, Minnesota, Mississippi, Missouri, Montana, Nebraska, Nevada, New Hampshire, New Mexico, North Carolina, North Dakota, Oklahoma, Oregon, Rhode Island, South Carolina, South Dakota, Tennessee, Utah, Vermont, Virginia, Washington, West Virginia, Wisconsin, and Wyoming.)

Read on for my assumptions and algorithm.

Assumptions

I made two simplifying assumptions. First, I assumed that the entire population of each state can vote. Second, I assumed that all states were winner-take-all. Maine and Nebraska are not, but I think I can justify this assumption: it would be "wasteful" to take one congressional district of Maine without taking the other districts and at-large votes.

I used apportionment data from the 2000 census for populations and numbers of electoral votes. The 2000 census controls electoral vote apportionment for 2004 and 2008. Since that data didn't include the population of DC, I got the population of DC from another source, which was also connected to the 2000 census but which used different criteria to determine whether a person counted as part of the population of a state.

Algorithm

To come up with an algorithm to solve the problem, I first thought about how the Electoral College problem would generalize:

Instance: populations[], electors[], goal. (Population needed to win each state, electoral college vote of each state, number of electoral votes I need to win.)

Solution: W, a set of states. (States that I win.)

Constraint: (sum over W of electors[]) >= g. (I win the election.)

Objective: minimize (sum over W of populations[]). (I win the election with the minimum popuplar vote.)

I noticed that the problem looked similar to Subset Sum, an NP-complete problem, so I thought about possible exponential-time algorithms:

Brute force, trying every possible W. This would take 2 51 for 50 states plus DC.

for 50 states plus DC. Backtracking (adding states to W until goal is reached). This would take at least 2 37 , since you can have the 37 smallest states and still need more electoral votes to win.

, since you can have the 37 smallest states and still need more electoral votes to win. Backtracking, taking advantage of the fact that several states have the same number of electoral votes. Sort the states by electoral votes and then by population. If we didn't add Wyoming (smallest state with exactly 3 electoral votes), we won't add any other states with exactly 3 electoral votes. Significantly faster than simple backtracking; might be fast enough.

I looked up Subset Sum in Garey and Johnson to see which exponential-time algorithm they recommended for Subset Sum. To my surprise, I found a fast dynamic programming algorithm. The algorithm is "pseudo-polynomial" -- its running time is a polynomial in the size of the input and the integer values represented by the input. The algorithm is only exponential because an integer can be represented using a number of bits equal to a log of its value. If the numbers are small, the dynamic programming algorithm is fast.

Once this algorithm is modified to apply to the Electoral College problem, it computes a two-dimensional table containing the minimum population needed for every exactly j electoral votes using only the first i states. Each cell of the table can be computed quickly by considering two cases, either the candidate wins state i, getting elec i electoral votes for pop i /2, or doesn't: minpop i,j = min(minpop i-1,j-elec i + pop i /2, minpop i-1,j ). The algorithm runs in O(states * electors) time. It is nice that the running time depends on the numbers of electors, not the populations.

I implemented the dynamic programming algorithm in ugly JavaScript. The JavaScript requires the print() function provided by my minimal JavaScript environment. On my computer, it takes about 3 seconds in IE or 1 second in Firefox.

Related work

After getting the answer of 21.8%, I searched Google for variations on "22% of the popular vote" and found several people who had have made similar calculations (some using approximate greedy algorithms, some using correct dynamic programming algorithms, all with different input data).