場合の数ですね。場合の数や確率を求める問題は、まず母関数の手法が使えるかどうか考えたほうが良いです。この問題はわかりやすいです。
Pk(x) = 1 + xk + x2k + ...
という母関数を考えます。各係数はkペンスだけ使ったときの場合の数です。例えば、k = 5として、x10の係数は1だから1通り、x11の係数は0だからそんな組合せはありません。また、
P1(x)P2(x) = (1 + x + x2 + x3 + ...)(1 + x2 + ...) = 1 + x + 2x2 + 2x3 + ...
のx3の係数の2は、(1p, 2p), (1p, 1p, 1p)の2通りを表しています。
この問題は、
P1(x)P2(x)P5(x)...P200(x)
のx200の係数を求めるだけです。
type Poly = Array[Int] val N = 200 val coins = List(1, 2, 5, 10, 20, 50, 100, 200) def series(c :Int) = Array.range(0, N + 1).map(k => if(k % c == 0) 1 else 0) def mul(f :Poly, g :Poly) = { val a = new Poly(N + 1) for(k <- Iterator.range(0, N + 1); l <- Iterator.range(0, N - k + 1)) a(k + l) += f(k) * g(l) a } def unit() : Array[Int]= Iterator.range(0, N + 1).map(k => if(k == 0) 1 else 0).toArray val f = coins.map(series).foldLeft(unit)(mul) println (f(N))