Method for assigning unique per-board addresses
My favorite is the Maxim DS2411. It's a small SOT-23 part which contains a unique SSN (Silicon Serial Number). Not very cheap in itself, but may be the cheapest overall, when you think of logistics overhead and programming cost in other solutions. The SSN solution doesn't require any manual intervention/operation in addition to the automated pick-and-place.
Risk of duplicate IDs is almost zero.
In a comment to this answer mikeselecticstuff pointed to these MAC address EEPROMs. They're common EEPROMs with a unique ID programmed in a write protected area of the EEPROM. They're cheaper than the DS2411, and have some storage for user data left.  

If you would like to "program" through soldering I would skip the 0\$\Omega\$ jumpers; soldering those simply takes too long. Instead place two half-circle pads 0.1mm apart. 



The operator simply has to lay a drop of solder over both halves to "program" one bit. Less than half the time (one solder point instead of two, and no component to pick and place), and no components required. So you save twice. And like Olin says, with the right size and gap, they are both easy to bridge and to unbridge.  

If your board has a microcontroller (which board doesn't these days?) you can have a serial number programmed in it by the programming service. Logistic cost on your side is minimum: just keep track of which serial they should start with at each programming batch.
Risk of errors resulting in duplicate IDs is low, depending on how well the programming service is organized, but I've known it happen.  

I've known about the following, but I didn't remember what they were called, and I also thought I needed a picture to explain it better.   


Apparently this is called a programmable DIP shunt. You use it like a DIP-switch, but instead of using miniature switches it uses weak connections which you can "program" by breaking them with a pen or small screwdriver.
This has the same big disadvantage as the selective soldering solutions: the operator must decide which connections to break and which should be left intact, and then human error is never far away. Reliability as far as uniqueness is concerned: low.