python面值組合 題目1 硬幣面值組合

2021-10-11 03:24:03 字數 1382 閱讀 9692

問題描述

評測題目: 給定 m 種面值的硬幣,每種面值的硬幣有無限多個,它們的面值分別為c=[c[0], c[1], …, c[m-1]],現用這些面值的硬幣湊齊 n 元,求有多少種方法。如 n=3, m=4, c =[8, 3, 1, 2],則有 3 種方法,分別為 、、 。

問題分析

給定乙個金額n,假設有m種面值的硬幣c=[c[0], c[1], …, c[m-1]],現用這些面值的硬幣湊齊 n 元,有

求所有可能的組合數,就是求滿足前面等值的係數x=[x[0], x[1], …, x[m-1]]的所有可能個數。

【思路1】 採用暴力列舉的方法,各個係數可能的取值分別為x[0] = , ……, x[m-1] = 。這適用於硬幣種類數較小的問題,但是複雜度很高o(n/c[0]×…×n/c[m-1]))

【思路2】 定義num[i,j]為用前i種硬幣(所有硬幣)湊齊j元的所有組合數,那麼題目的問題實際上就是求num[m,n]。設k為使用面值為c[m-1]的硬幣湊齊n元所允許的最大個數,那麼所有可能的組合數可以表示為c[m-1]的個數j從0個一直變到k個的時候滿足n-j*c[m-1]的所有組合數之和。也就是說,我們通過固定最後一種面值的硬幣數量,來求取剩餘面值硬幣湊齊餘額的組合數。因此,對num[m,n],有

由此式可以看出此表示式可用遞迴的方法,逐步縮減問題的規模,然後求解。下面討論遞迴的初始值,即num[i,0]的情況。顯然如果n=0,那麼無論有前多少種來組合0,只有一種可能,就是各個係數都等於0,所以對每乙個i,都有num[i][0] = 1。

python**

# 評測題目: 給定 m 種面值的硬幣,每種面值的硬幣有無限多個,

# 它們的面值分別為 c=[c[0], c[1], …, c[m-1]],

# 現用這些面值的硬幣湊齊 n 元,求有多少種方法。

# 如 n=3, m=4, c =[8, 3, 1, 2],則有 3 種方法,分別為 、、 。

import numpy as np

def combination(c,n,m):

num = np.zeros((m + 1, n + 1)) # num[i,j]為用前i種硬幣(所有硬幣)湊齊j元的所有組合數

for i in range(m+1):

num[i][0] = 1

for i in range(1,m+1):

for j in range(1,n+1):

for k in range(j//c[i-1]+1):

num[i][j] += num[i-1][j-k*c[i-1]]

return num[m][n]

c = np.array([8,1,2,3])

n = 3

m = 4

print('%d' %(combination(c,n,m)))

參考文獻

7621 硬幣面值組合

描述 使用1角 2角 5角硬幣組成 n 角錢。設1角 2角 5角的硬幣各用了a b c個,列出所有可能的a,b,c組合。輸出順序為 先按c的值從小到大,若c相同則按b的值從小到大。輸入乙個整數n 1 n 100 代表需要組成的錢的角數。輸出輸出有若干行,每行的形式為 i a b c 第1列i代表當前...

騰訊 硬幣面值組合問題

題目描述 有n種不同面值的硬幣,每種面值的硬幣都有無限多個。為了方便攜帶,希望帶盡量少的硬幣,並且要能組合出1到m之間 包括1和m 的所有面值。輸入第一行包含兩個整數m,n,含義如題目所述。第二行包含n個整數,第i個整數表示第i種硬幣的面值。輸出輸出乙個整數,表示最少需要攜帶的硬幣數量。如果無解,則...

硬幣面值組合(上台階)

假設我們有8種不同面值的硬幣 1,2,5,10,20,50,100,200 用這些硬幣組合夠成乙個給定的數值n。問總過有多少種可能的組合方式?類似的題目還有 華為面試題 1分2分5分的硬幣三種,組合成1角,共有多少種組合 創新工廠筆試題 有1分,2分,5分,10分四種硬幣,每種硬幣數量無限,給定n分...