Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Q&A
GeeksQuiz
DynamicProgramming|Set7(CoinChange)
GivenavalueN,ifwewanttomakechangeforNcents,andwehaveinfinitesupplyofeachofS={S1,S2,..,
Sm}valuedcoins,howmanywayscanwemakethechange?Theorderofcoinsdoesntmatter.
Forexample,forN=4andS={1,2,3},therearefoursolutions:{1,1,1,1},{1,1,2},{2,2},{1,3}.Sooutputshouldbe
4.ForN=10andS={2,5,3,6},therearefivesolutions:{2,2,2,2,2},{2,2,3,3},{2,2,6},{2,3,5}and{5,5}.Sothe
outputshouldbe5.
1)OptimalSubstructure
Tocounttotalnumbersolutions,wecandivideallsetsolutionsintwosets.
1)Solutionsthatdonotcontainmthcoin(orSm).
2)SolutionsthatcontainatleastoneSm.
Letcount(S[],m,n)bethefunctiontocountthenumberofsolutions,thenitcanbewrittenassumofcount(S[],
m1,n)andcount(S[],m,nSm).
Therefore,theproblemhasoptimalsubstructurepropertyastheproblemcanbesolvedusingsolutionsto
subproblems.
2)OverlappingSubproblems
FollowingisasimplerecursiveimplementationoftheCoinChangeproblem.Theimplementationsimplyfollows
therecursivestructurementionedabove.
#include<stdio.h>
//ReturnsthecountofwayswecansumS[0...m1]coinstogetsumn
intcount(intS[],intm,intn)
{
//Ifnis0thenthereis1solution(donotincludeanycoin)
if(n==0)
return1
//Ifnislessthan0thennosolutionexists
if(n<0)
return0
//Iftherearenocoinsandnisgreaterthan0,thennosolutionexist
if(m<=0&&n>=1)
return0
//countissumofsolutions(i)includingS[m1](ii)excludingS[m1]
returncount(S,m1,n)+count(S,m,nS[m1])
}
//Driverprogramtotestabovefunction
intmain()
{
inti,j
intarr[]={1,2,3}
intm=sizeof(arr)/sizeof(arr[0])
printf("%d",count(arr,m,4))
getchar()
return0
}
RunonIDE
Itshouldbenotedthattheabovefunctioncomputesthesamesubproblemsagainandagain.Seethefollowing
recursiontreeforS={1,2,3}andn=5.
ThefunctionC({1},3)iscalledtwotimes.Ifwedrawthecompletetree,thenwecanseethattherearemany
subproblemsbeingcalledmorethanonce.
C() --> count()
C({1,2,3}, 5)
/
\
\
C({1,2}, 5)
/
C({1,2,3}, 2)
/
/
/
/
\
\
C({1,2}, 3)
/
\
/
\
C({1,2},1) C({1},3)
/\
/ \
. .
/\
/ \
.
C({1}, 5)
/
\
/
\
C({1}, 4) C({}, 5)
/
/
\
\
C({1}, 3) C({}, 4)
/ \
/
.
\
.
Sincesamesuproblemsarecalledagain,thisproblemhasOverlappingSubprolemsproperty.SotheCoin
Changeproblemhasbothproperties(seethisandthis)ofadynamicprogrammingproblem.Likeothertypical
DynamicProgramming(DP)problems,recomputationsofsamesubproblemscanbeavoidedbyconstructinga
temporaryarraytable[][]inbottomupmanner.
DynamicProgrammingSolution
#include<stdio.h>
intcount(intS[],intm,intn)
{
inti,j,x,y
//Weneedn+1rowsasthetableisconsturctedinbottomupmannerusing
//thebasecase0valuecase(n=0)
inttable[n+1][m]
//Filltheenteriesfor0valuecase(n=0)
//Filltheenteriesfor0valuecase(n=0)
for(i=0i<mi++)
table[0][i]=1
//Fillrestofthetableenteriesinbottomupmanner
for(i=1i<n+1i++)
{
for(j=0j<mj++)
{
//CountofsolutionsincludingS[j]
x=(iS[j]>=0)?table[iS[j]][j]:0
//CountofsolutionsexcludingS[j]
y=(j>=1)?table[i][j1]:0
//totalcount
table[i][j]=x+y
}
}
returntable[n][m1]
}
//Driverprogramtotestabovefunction
intmain()
{
intarr[]={1,2,3}
intm=sizeof(arr)/sizeof(arr[0])
intn=4
printf("%d",count(arr,m,n))
return0
}
RunonIDE
TimeComplexity:O(mn)
Followingisasimplifiedversionofmethod2.TheauxiliaryspacerequiredhereisO(n)only.
intcount(intS[],intm,intn)
{
//table[i]willbestoringthenumberofsolutionsfor
//valuei.Weneedn+1rowsasthetableisconsturcted
//inbottomupmannerusingthebasecase(n=0)
inttable[n+1]
//Initializealltablevaluesas0
memset(table,0,sizeof(table))
//Basecase(Ifgivenvalueis0)
table[0]=1
//Pickallcoinsonebyoneandupdatethetable[]values
//aftertheindexgreaterthanorequaltothevalueofthe
//pickedcoin
for(inti=0i<mi++)
for(intj=S[i]j<=nj++)
table[j]+=table[jS[i]]
returntable[n]
}
RunonIDE
ThankstoRohanLaishramforsuggestingthisspaceoptimizedversion.
Pleasewritecommentsifyoufindanythingincorrect,oryouwanttosharemoreinformationaboutthetopic
discussedabove.
References:
http://www.algorithmist.com/index.php/Coin_Change
RelatedPosts:
GITLetsGetIntoIt
Howtolearnanytechnologyinsideout?
BitmaskingandDynamicProgramming|Set1(Countwaystoassignuniquecaptoeveryperson)
SAPLabsInterviewExperience|Set11(OnCampus)
MistakesToAvoidWhileBuildingAnECommerceApp
WooqerInterviewExperience|Set1(onCampus)
FactsetInterviewExperience|Set3(OnCampus)
Findallpossibleoutcomesofagivenexpression
Like
49
Tweet
15
Writingcodeincomment?Pleaseusecode.geeksforgeeks.org,generatelinkandsharethelinkhere.
163Comments
Recommend 6
GeeksforGeeks
Share
Jointhediscussion
Login
SortbyNewest
TusharDwivedi 15daysago
Isolvedthisproblemwithallthethreeways.ie.Recursion,DPmemoization,andDP
tabulation.
C++implementation:https://ideone.com/14bBIv
.
Belowweretheresults:
(Inputtakenviastdin)
Forn=10
recursion:0secondsand14microseconds
memoization:0secondsand17microseconds
tabulation:0secondsand17microseconds
Forn=100
recursion:0secondsand1300microseconds
memoization:0secondsand1270microseconds
tabulation:0secondsand35microseconds
WhatIamunabletounderstand,isthatwhyforslightlylargerinput,memoizationis
takingalmostsameamountoftimeassimplerecursivesolution?Shouldn't
memoizationtakeevenlessertimethantabulationinthiscase,asitskipsmanyuseless
calculationsfromthematrix,thathavetobedoneincaseoftabulation?Orisitdueto
recursivecalls?
Reply Share
ArpitQuickgunArora 18daysago
explanationforbottomupmethod
justconvertthelogiccount(S,n,m)=count(S,nSm,m)+count(S,n,m1)totable
form
table[n][m]=table[n][m1]+table[ns[m]][m].
sincewehavealreadyinitialisedthevaluesforn=0andm=0(if(n%s[0]==0)then
table[n][0]=1),wecanrunloopfromn=1onwardsandfillthetable.
Also,ifn<0,return0
Nowwhilefillingthetable,wecannoticethattofindanycellvalue,wejustvaluesfrom
thepreviousrowandfromthesamerowforlesservaluesofn(whichhavealreadybeen
filled).Usingthis,thespaceoptimisedversioncanbederived.
Reply Share
dividebyzero 22daysago
Inthelastcase,shouldn'titbe`for(intj=S[i]j<=nj+=S[i])`?
Reply Share
Mandeep>dividebyzero 17daysago
Mandeep>dividebyzero 17daysago
EvenIhadthesamedoubt,butlaterIfiguredthisout.
Supposeuhavecoins{1,3}withn=5.
Supposethatyouhavealreadyprocessedthejloopforcoin1,thatleaveyou
withtableas{1,1,1,1,1,1}sinceallvaluesfrom0to5canbedoneinonly1
way(i.e.usingall1's).
NowthinkthatyouareprocessingthejloopforS[i]=3.
Thatmeansyouhaveanewwaytomakevalue3(111,3).
souupdatetable[3]to2.Butaccordingtoyourlogic,itshouldtrytoupdatethe
nextvalueoftable[6](sinceaccordingtoyou,j+=S[i]).Butthinkaboutthecase
of4.Don'tyouhaveanewwaytomakechangefor4??onewas1111,nowthe
newoneis1,3.
Becauseofthisreason,youdoj++andNOTj+=S[i].
Reply Share
GokulNC 23daysago
Howdoyoufindtheleastnumberofcoinsrequiredthatcanmakeanydesiredamount
??
Reply Share
ddddd 24daysago
2nddpapproachiswrong,duplicatesarecountedaswell
Reply Share
ddddd>ddddd 24daysago
ifyourorderofcoinsinthesolutionmattered,thensecondapproachisright
Reply Share
Anthony amonthago
IdidnotunderstandtheDPlogic.Istruggledforhours.Cananyonehelpmeouton
howthealgorithmworks?
Reply Share
AbhishekTiwari amonthago
Ihaveaquery.
Wouldthismethodnotwork...??
Supposewehavetofindthesumx.
AndcoinsallowedarecontainedinarrayA.
Then
foriinA:
Count(x)+=(Count(xi))
?
Ifnotthenwhat'stheproblem(insteadofmemoryoverflow,whichcanalwaysbe
eliminatedusingDPtable.)
Reply Share
AadilAhmad amonthago
whatifordermatters.like1,1,2isdifferentfrom2,1,1.
Reply Share
Vivek amonthago
TopDownApproach
http://ideone.com/fHO2Ab
Reply Share
ManoharTn amonthago
Ididcodeintheotherway,Iconsideredways[m][n]wheremisthenumberofcoins
andnisthevaluetomake.
Hereisthecodeandletmeknowifthere'sanycasei'mmissingoutorifthere'sany
error.
http://ideone.com/hzzxze
Reply Share
RajanParmar 2monthsago
whyfirstrowoftableisfilledwith'1'?
Reply Share
Marquis>RajanParmar 2monthsago
Thisistocoveryourbasecases.Itseasiesttoseehowthiscomesintoplayif
youwriteoutthetablebyhandfollowingallofthevariablesasifyouwerethe
compiler.
Reply Share
roshanl 2monthsago
solution(2)iswrong.Itwillcountduplicatecombinationsaswell(fordenominations
1,2,3andtargetcount4,itwillcount1+1+2and1+2+1)
Reply Share
SaurabhKumar>roshanl 13daysago
{1,1,1,1},{2,2},{3,1},{1,1,2}ansthesolutionisright
Reply Share
Goku 2monthsago
@geeksforgeeks
@geeksforgeeks
Thisisthevarientforcoinchangeproblem.Inthiswehavetofindtheminimumnumber
ofcoinsrequiredtogetthegivensumfromthesetofcoinvaluesgiven.Pleasepublishit
:)
http://ideone.com/B7Ej9H
Reply Share
abhi>Goku amonthago
Yourvariantiswrongonsometestcases,
saycoinarrayis1,2,3,4,5anduhavetomake15
theo/pshouldbe5,
butyourprogram'so/pis3
Reply Share
Goku>abhi amonthago
broanswerwouldbe3only.Wehavetofindtheminimumno.of
coins.Using3coinseachofvalue5,wecangetthesumas15.
Reply Share
NIKHILSINGH 2monthsago
simplebottomupapproach
http://ideone.com/raTq4l
Reply Share
Ajcoo 2monthsago
GuysIamnotsureifthissolutionusesDP.Pleasetakealookandcomment..
http://ideone.com/GpI1Vg
Reply Share
SwapnilJain>Ajcoo amonthago
Yoyoyoamigo,that'sdp...
Reply Share
Utkarsh 2monthsago
WHYITDOESN'TWORKFOR1stexamplebutforsecond
#include<stdio.h>
intcount(intdp[5],ints[3],int,int)
intmain()
{
ints[3]={1,2,3}
ints[3]={1,2,3}
intdp[5]={0}
intm=2//mistheindexoflastelementinsets
intn=4
printf("%d",count(dp,s,m,n))
return0
seemore
Reply Share
Utkarsh>Utkarsh 2monthsago
printf("n=%dm=%ddp[n]=%d\n",n,m,dp[n])wasfordebuggingpurpose,,no
meaningtosolution
Reply Share
CarmelinaContarino 2monthsago
Howwouldweprintallthecombinationsofthecoinsusedforchange?
Notjustthe#ways...
Reply Share
Goku>CarmelinaContarino 2monthsago
backtracking
Reply Share
SrinivasPittala>Goku 2monthsago
tracingback
Reply Share
CarmelinaContarino>SrinivasPittala 2monthsago
Iguessnobacktrackingandneithertracingback:(
Reply Share
Arnab 3monthsago
Ithinkthesimplifiedversionofmethodtwoconsidersthesequencealso.i.e(3,3,5)and
(3,5,3)tosequenceareconsidereddifferent.
1
Reply Share
Raj>Arnab 2monthsago
Justdothis.
table[j]+=jS[i]>=0?table[jS[i]]:0
Reply Share
AbhishekJaisingh>Arnab 3monthsago
absolutely!
Reply Share
Abhi 3monthsago
cananyoneexplainthelogicofthesimplifiedversionofmethod2??
Reply Share
Sathiyaseelan>Abhi 2monthsago
Considerthefollowing,
Thesimplifiedapproach2isarrivedwiththebelowapproach,
Considertherowsascoins,andcolumnsarefrom1..N
sotheloopwillbecome,
Soateachouteriteration(foreachcoin),wejustneedthepreviousrow,instead
oftheentire2darray(ithrowdependsoni1throwonly)
Whichleadstothesimplifiedapproachof2.
Withsinglerow,beforeeachiteration,thesingle_rowcontainsvaluesof
previousiteration,inwhichwecanaddthevalues.
Atendofeachiteration,thesingle_rowcontainsthecurrentrowvalueswith
previousrowvalues.
for(inti=0i<mi++)for(int=""j="0j<=nj++)"didn't=""mention=""the=""base=""
cases=""dp[i][j]=""+="dp[i1][j]"hope=""it=""helps="">
2
Reply Share
Vishlesh>Abhi 2monthsago
Abhididugotanyreplyorunderstoodlogicbehindmethod2?
Reply Share
Abhi>Vishlesh 2monthsago
didntgotanyreply..pleaseexplain..
andthanxfortheconcernbro
Reply Share
Shitiz 3monthsago
IfIrunthelastmethodonarr[]={2,3}andsum=4,answershouldbe2butitisgiving1.I
don'tknowwhy?Pleasecheck
Reply Share
Shitiz>Shitiz 3monthsago
SorryImisreadtheproblem
Reply Share
abhi 3monthsago
whatisthetimecomplexityofmethod1?
Reply Share
HuntXT>abhi 2monthsago
Itwouldbeexponential,2^(n),althoughderivingtheexactwouldbebitlengthy
anddifficult.
Sinceateachmomentwehavetwochoices,itwouldbeabinarytree,now,
ateachheightofbinarytreewearedoingsomeconstantwork,so,time
complexityateachlevel=>no.ofelementsatthatlevel*C[someconstant]
Thiswearedoingforthecompletetree,
hencetotalno,ofelementare:
1+2^1+2^2+2^3+......2^k,wherekisheightoftree....
=>2^(k+1)1
Now,tofindk,wecanapproxthatkmaybe(m1+N/s[0]),
aswearenotdoinganythingtillthem1thenatthesmallestdenominationwe
aremakingthechange.
Reply Share
akashdwivedi 3monthsago
cananyonepleasetellthemistakeerrorwasshowingofsegmentationfault
https://ideone.com/l2sAwM
Reply Share
Return_0>akashdwivedi 3monthsago
arr[size1]shouldbethereinsteadofarr[size]..
Reply Share
akashdwivedi>Return_0 3monthsago
thanks
Reply Share
wa 5monthsago
privatestaticintminNumberOfCoinsSumRecur(intv[],intn){
Arrays.fill(t,Integer.MAX_VALUE)
if(n<0)
if(n<0)
returnInteger.MAX_VALUE
if(n==0)
return0
if(t[n]!=Integer.MAX_VALUE)
returnt[n]
intans=Integer.MAX_VALUE
t[0]=0
for(inti=0i<v.lengthi++){
for(intj=v[i]j<=nj++){
t[j]=Math.min(1+t[jv[i]],t[j])
}
}
returnt[n]
}
privatestaticintminNumberOfCoinsSum(int[]arr,intsum){
Arrays.fill(t,Integer.MAX_VALUE)
t[0]=0
for(inti=0i<arr.lengthi++){
for(intj=arr[i]j<=sumj++)
t[j]=Math.min(t[j],1+t[jarr[i]])
}
returnt[sum]
}
Reply Share
Neha 5monthsago
HowtoprintthecombinationsiniterativeDPSolutionMethod1?
Reply Share
Saurabh 6monthsago
http://ideone.com/cA9ShC
Thisisasimplecodewithoutsubstructures.
Reply Share
TechieMe 6monthsago
Wonderfulexplanation..Reallyappreciateyoureffort...HereisaJavaversionofthe
applicationandamuchdeeperdiveintotheapproach.
http://techieme.in/minimumnum...
Reply Share
MissionPeace 7monthsago
https://www.youtube.com/watch?...
1
Reply Share
VivekH>MissionPeace 2monthsago
Pleasereadthequestionsproperly.Itaskhowmanydifferentwaysyoucan
havesothatsumisequaltoagivenvalue.Whereasthisvideocalculatesthe
minimumnumberofcoinstogettothegivenSum
Reply Share
MissionPeace 7monthsago
https://www.youtube.com/watch?...
1
Reply Share
Abhi 7monthsago
GeeksforGeekswecanusethissimplemethod
intcount(intarr[],ints,intm)//sisthenumberofcoininarray
//misthenumberwhichwewanttoget//fromthegivencoins
{
intdp[m+1]
dp[0]=0
inti
intj
for(i=1i<=mi++)
{
dp[i]=0
for(j=0j<sj++){=""if(i="">=arr[j]&&dp[i]<dp[iarr[j]]+1){=""dp[i]="dp[iarr[j]]+1"}=""
}=""}=""return=""dp[m]=""}="">
Reply Share
Loadmorecomments
@geeksforgeeks,SomerightsreservedContactUs!AboutUs!Advertisewithus!