动态规划法
# KY14 最小邮票数
# 邮票需要凑的总面值为M,可选邮票的总数是N
# 邮票i的面值保存为values[i]
# 动态规划法求解,dynamic programming
# 令 dp[i][j]表示只允许总前i张邮票中
# 选择,并且凑到总面值j,所需最小邮票数量
# 边界条件,若: i*j == 0, 则dp[i][j] = 0
# 求解dp[i][j]:
# 若:j<values[i],则dp[i][j] = dp[i-1][j]
# 若:j==values[i],则dp[i][j] = 1
# 若:j>values[i],
# 若:dp[i-1][j-values[i]] > 0,
# 若dp[i-1][j]>0:
# 则dp[i][j] = min([1+dp[i-1][j-values[i]],dp[i-1][j]])
# 否则:dp[i][j] = 1 + dp[i-1][j-values[i]]
# 若:dp[i-1][j-values[i]] < 0,则dp[i][j] = dp[i-1][j]
def print_min_amount(TotalValue, StampAmount):
values = (0,) + tuple(map(eval, input().strip().split()))
dp = [[0 for j in range(1+TotalValue)] for i in range(1+StampAmount)]
for i in range(1, 1+StampAmount):
for j in range(1, 1+TotalValue):
if j < values[i]:
dp[i][j] = dp[i-1][j]
elif j == values[i]:
dp[i][j] = 1
else: # j > values[i]
if dp[i-1][j-values[i]] > 0:
if dp[i-1][j]>0:
dp[i][j] = min([
1 + dp[i-1][j-values[i]],
dp[i-1][j]
])
else:
dp[i][j] = 1 + dp[i-1][j-values[i]]
else:
dp[i][j] = dp[i-1][j]
print(dp[StampAmount][TotalValue])
if __name__ == '__main__':
try:
while True:
TotalValue = eval(input().strip())
StampAmount = eval(input().strip())
print_min_amount(TotalValue, StampAmount)
except EOFError:
pass
空间优化版:
# KY14 最小邮票数
# 邮票需要凑的总面值为M,可选邮票的总数是N
# 邮票i的面值保存为values[i]
# 动态规划法求解,dynamic programming
# 令 dp[i][j]表示只允许总前i张邮票中
# 选择,并且凑到总面值j,所需最小邮票数量
# 边界条件,若: i*j == 0, 则dp[i][j] = 0
# 求解dp[i][j]:
# 若:j<values[i],则dp[i][j] = dp[i-1][j]
# 若:j==values[i],则dp[i][j] = 1
# 若:j>values[i],
# 若:dp[i-1][j-values[i]] > 0,
# 若dp[i-1][j]>0:
# 则dp[i][j] = min([1+dp[i-1][j-values[i]],dp[i-1][j]])
# 否则:dp[i][j] = 1 + dp[i-1][j-values[i]]
# 若:dp[i-1][j-values[i]] < 0,则dp[i][j] = dp[i-1][j]
# 法二,空间优化版
# 改进版: 减少空间占用
def print_min_amount(TotalValue, StampAmount):
stampsValues = (0,) + tuple(map(eval, input().strip().split()))
dp = [0 for j in range(1 + TotalValue)]
for stampIndex in range(1, StampAmount + 1):
for value in range(TotalValue, 0, -1):
if stampsValues[stampIndex] == value:
dp[value] = 1
elif stampsValues[stampIndex] > value:
pass # dp[value] = dp[value]
else: # stampsValues[stampIndex] < value
if dp[value-stampsValues[stampIndex]] > 0:
if dp[value] > 0:
dp[value] = min([
1 + dp[value-stampsValues[stampIndex]],
dp[value]
])
else:
dp[value] = 1 + dp[value-stampsValues[stampIndex]]
else:
pass # dp[value] = dp[value]
print(dp[TotalValue])
if __name__ == '__main__':
try:
while True:
TotalValue = eval(input().strip())
StampAmount = eval(input().strip())
print_min_amount(TotalValue, StampAmount)
except EOFError:
pass