Scripts are one of the smartest features in Bitcoin. The most obvious way to implement cryptocurrency is to transfer to a public key. To claim the transfer, you sign with the corresponding private key. This is not how Bitcoin works.
When you send Bitcoins (the outside transaction), you send them to a script. When you claim Bitcoins (the in) of a transaction) you claim them with a script. To determine whether a transaction input correctly claims a transaction output, the two scripts are combined and the result is executed. If the result is true, then entry demands exit. The scripting language is stack based and roughly similar to Forth.
The transaction entry (the script trying to claim the Bitcoins) runs first. It will usually put a public key and a signature on the stack. Then the output (the script whose Bitcoins are claimed) runs. It will usually confirm that the public key is correct and that the signature signs the transaction with the corresponding private key.
So you get the same effect as if you just specified a public key and signature, but you have the option of specifying more complex scripts. Unfortunately, this simple script type is about the only script type currently supported. The original developer (s) came up with much more interesting scripts, including contracts, multi-party signatures, etc.
M of N signatures are expected. This way you can list, say 3 public keys such that 2 of them could claim the Bitcoins.
Unfortunately, some of the scripting components are feared to have security risks, so many of them are currently disabled.