版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shaoyou223/article/details/82871208
核心思想:
在我们从 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