I want to find out how many ways there are to make 500 using only 1, 2, 5, 10, 20, 50, 100, and 200. I understand that there exist greedy algorithms etc that can solve this type of question, but I want to be able to do it the following way:
The number of integer partitions of a given number, n, using only numbers from some set T, can be obtained from the coefficient of the xn term in the product of all (1-xt)-1, where t is in T.
To do this, note that the Taylor expansion of (1-xt)-1 equals (1+xt+x2t+...). Here is the code I've written so far:
#################################
# First, define a function that returns the product of two
# polynomials. A list here
# represents a polynomial with the entry in a list corresponding to
# the coefficient of the power of x associated to that position, e.g.
# [1,2,3] = 1 + 2x + 3x^2.
#################################
def p(a,v):
"""(list,list) -> list"""
prodav = [0]*(len(a)+len(v)-1)
for n in range(len(a)):
for m in range(len(v)):
prodav[n+m] += v[m]*a[n]
return prodav
#################################
# Now, let a,b,c,...,h represent the first 501 terms in the Taylor
# expansion of 1/(1-x^n), where n gives the coin value, i.e
# 1,2,5,10,20,50,100,200 in pence. See the generating function
# section in https://en.wikipedia.org/wiki/Partition_(number_theory).
# Our function, p, multiplies all these polynomials together
# (when applied iteratively). As per the Wiki entry, the coefficient
# of x^t is equal to the number of possible ways t can be made,
# using only the denominations of change available, a so called
# 'restricted integer partition'. Note that it isn't necessary to
# consider the entire Taylor expansion since we only need the
# 500th power.
#################################
a = ( [1] ) * 501 # 1
b = ( [1] + [0] ) * 250 + [1] # 2
c = ( [1] + [0]*4 ) * 100 + [1] # 5
d = ( [1] + [0]*9 ) * 50 + [1] # 10
e = ( [1] + [0]*19 ) * 25 + [1] # 20
f = ( [1] + [0]*49 ) * 10 + [1] # 50
g = ( [1] + [0]*99 ) * 5 + [1] # 100
h = ( [1] + [0]*199 ) * 2 + [0]*101 # 200
x = p(h,p(g,p(f,p(e,p(d,p(c,p(b,a)))))))
print(x[500]) # = 6290871
My problem is that I'm not confident the answer this gives is correct. I've compared it to two other greedy algorithms whose outputs agree with each other, but not mine. Can anyone see where I might have gone wrong?