Sei sulla pagina 1di 13

IDE

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}, -1) C({1,2}, 2)


/
\
/
\
C({1,2},0) C({1},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

163Comments Category: Misc Tags: DynamicProgramming

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&lt=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!

Potrebbero piacerti anche