Here it is, in its most compact (and least human-readable) form:
Read the extensively commented source code if you are interested in its inner workings.
The compact form can be conveniently pasted into a running instance of dc, or - better yet - into an initialization file, if the dc version you use allows such a mechanism. For example, GNU dc allows a script file to be read before accepting input from STDIN. Like this:
$ dc -f ~/etc/my_macros.dc -
The initial 0 is a sequence terminator (first in, last out!). When encountered while consuming the stack, it marks the end of datum/weight pairs: this allows for an arbitrary number of pairs. The lwx means: load macro w (WAM itself) and execute it. The final p prints the result.
0 datum1 weight1 datum2 weight2 ... ... datumn weightn lwx p