space optimized solution for coin change
First note that table[i] is number of ways for coin change when N=i.
Given Algorithm fills this array (table[]) as per given set of coin (S[]). Initially all values in table[] are initialized to 0. And table[0] set to 0 (this is base case N=0).
Each coin adds up values in table[] in following manner.
For coin of value X, following are updates to table[] -
table[X] = table[X] + 1
This is easy to understand. Specifically this adds solution {X}.
for all Y > X
table[Y] = table[Y] + table[Y-X]
This is tricky to understand. Take example X = 3, and consider case for Y = 4.
4 = 3 + 1 i.e. 4 can be obtained by combining 3 and 1. And by definition number of ways to get 1 are table[1]. So that many ways are added to table[4]. Thats why above expression uses table[Y-X].
Following line in your algorithm represents the same (above two steps) -
table[j] += table[j-S[i]];
At the end of algorithm, table[n] contains solution for n.
Try to understand the algorithm using this way.
table[i][j]
means using the first i
types of coins to make change for value j
. then:
table[i][j] = table[i-1][j] + table[i][j-S[i]]
Clearly when making up j
coins, you have two choices. not using the ith coin or using the ith coin. When not using the ith coin, the solution number is table[i-1][j]
. When using the ith coin, the solution number is table[i][j-S[i]]
, which means using the first i coins to make up j-S[i] value.Therefore, the total is the sum of both, which is table[i-1][j] + table[i][j-S[i]]
In the code, you will see the for loop. the outer loop iterate over i and the inner loop iterate over j. the +=
statement calculate table[i][j]
based on the equation above.
EDIT
table[j]
in your code is actually the table[i][j]
I am talking above and i
is the value in your loop. after the loop table[N]
means table[M][N]
, representing using first M
coins, which are all the coins, to make value for N
.
I will provide more detail based on the code:
for(int i=0; i<m; i++)
for(int j=S[i]; j<=n; j++)
table[j] += table[j-S[i]];
When i = 0
, table[j]
means using the first 1 coins to make changes for value j
. for example, table[2]
right now means using coins {1}
to make change for 2. So:
table[1] = table[1] + table[1 - S[0]] = table[1] + table[0] = 1 + 0= 1
table[2] = table[2] + table[2 - S[0]] = table[2] + table[1] = 0 + 1= 1
table[3] = 1
table[4] = 1
After that, we got the results when i = 0. table[1] ~ table[4]
now means using coin {1}
to make change for values 1, 2, 3, 4 separately.
When i = 1, table[j]
means using coin {1, 2}
to make changes for value j
.
table[2] = table[2] + table[2 - S[1]] = table[2] + table[0] = 1 + 1= 2
table[3] = table[3] + table[3 - S[1]] = 1 + 1 = 2
table[4] = table[4] + table[4 - S[1]] = table[4] + table[2] = 1 + 2 = 3
The following process is the same.
Finally, We take table[4]
when i = 1
out and analyze it:
table[4] = table[4] + table[4 - S[1]] = table[4] + table[2] = 1 + 2 = 3
Here table[4]
on the left is the value we are calculating and actually it is table[i=1][4]
. table[4]
on the right represents the previous value and in this case, table[i=0][4]
. It could expand to:
table[i=1][4] = table[i=0][4] + table[i=1][4 - S[1]]
the equation is exactly
table[i][j] = table[i-1][j] + table[i][j-S[i]]
EDIT Follow-Up question
If you think you really understand this question, try to solve the same problem with a new constraint. What if every coin can only be used once? For example, N = 4 and S = {1,2,3}, only one solution {1,3} so the output should be 1. And For N = 10 and S = {2, 5, 3, 6}, still only one solution {2, 3, 5} and the output is 1.
Hint: only one line change of original code is enough.
Answer:http://ideone.com/t1JnEz