1. 程式人生 > >動態規劃 硬幣問題,求最大、最小可以組成一個錢數的數

動態規劃 硬幣問題,求最大、最小可以組成一個錢數的數

核心思想:

        在我們從 1 元開始依次找零時,可以嘗試一下當前要找零的面值(這裡指 1 元)是否能夠被分解成另一個已求解的面值的找零需要的硬幣個數再加上這一堆硬幣中的某個面值之和,如果這樣分解之後最終的硬幣數是最少的,那麼問題就得到答案了。這就是動態規劃的思想。

python程式明天寫:

藍本為:

#有n種硬幣,面值分別為V1,V2,…,Vn, 每種有無限多。給定非負整數S,可以選用多少硬幣,使得面值之和恰好為S,輸出硬幣數目的最小值和最大值。(1<=n<=100,0<=S<=10000,1<=Vi<=S)。
#完全揹包,可以選擇無限次某個物品,來達到某個(重量)。
#把S看做重量和,把硬幣的面值看重量,把硬幣個數當做是價值(也就是1)。
#嘗試動態規劃

v = [1,2,5]
S = 9

dmin = [1000]*(S+1)#用來存放能湊出面值i的最少硬幣數,比如dmin[30]表示可以湊出30塊錢的最少硬幣書
dmin[0] = 0
dmax = [-1000]*(S+1)
dmax[0] = 0
path_min= [0]*(S+1)
for i in range(1,S+1):
    for j in range(len(v)):
        #如果i-v[j]<0,表示i比任何一個幣值的小,所以跳過
        print('此時i:%d,j:%d'%(i,j))
        if i-v[j]<0:
            print('i-v[j]<0,,,i:%d,v[j]:%d'%(i,v[j]))
            print('----------------------------------')
            continue
        else:#動態規劃
            print('i-v[j]>=0,,,i:%d,v[j]:%d'%(i,v[j]))
            if dmin[i]>dmin[i-v[j]]+1:
                print('dmin[%d]>dmin[%d-%d]+1'%(i,i,v[j]))
                dmin[i] =dmin[i-v[j]]+1
                print('把值%d給dmin[%d]'%(dmin[i-v[j]]+1,i))
            if dmax[i] < dmax[i - v[j]] + 1:
                print('dmax[%d]<dmax[%d-%d]+1' % (i, i, v[j]))
                dmax[i] = dmax[i - v[j]] + 1
                print('把值%d給dmax[%d]' % (dmax[i - v[j]] + 1, i))

print(dmin)
print(dmax)
#dmin[-1]就是最小值
#dmax[-1]就是最大值

'''
#這種求得是有多少種表示方法
ways = [0]*(S+1)
ways[0]=1
for i in range(7):
    for j in range(v[i],S+1):
        ways[j] = ways[j]+ways[j-v[i]]
print(ways)
'''

zuidazhi