0
410^4
104枚來自各個星球的硬幣,需要請你幫她盤算一下,是否可能精確湊出要付的款額。
輸入格式:
輸入第一行給出兩個正整數:n(≤10
4≤10^4
≤104
)是硬幣的總個數,m(≤10
2≤10^2
≤102
)是韓梅梅要付的款額。第二行給出 n 枚硬幣的正整數面值。數字間以空格分隔。
輸出格式:
在一行中輸出硬幣的面值 v1≤v2≤⋯≤vk,滿足條件 v1+v2+…+vk=m。數字間以 1 個空格分隔,行首尾不得有多餘空格。若解不唯一,則輸出最小序列。若無解,則輸出 no solution。
注:我們說序列比「小」,是指存在 k≥1 使得 a[i]=b[i] 對所有 i8 9
5 9 8 7 2 3 4 1
1 3 5
4 87 2 4 3
no solution根據題目給出的問題,首先想到用dfs思想,遍歷整個陣列,依次相加找到符合的答案,但這樣可能會有多組答案,題目要求最小序列,那麼首先可以將輸入的金額由小到大排序,這樣遍歷出來的序列就是最小序列。(ps:後來分析之後考慮到使用新學的動態規劃思想也能解決該問題。)
題目中關鍵的乙個檢測點就是當所有的數額相加之後小於要求的數額時,要退出返回,不用去執行遞迴。
import numpy
n,m =
input()
.split(
" ")
m =int
(m)n =
int(n)
f =0
temp =
0p =
0arr =[0
]*nstr=
input()
.split(
" ")
for i in
str:
arr[p]
=int
(i) p+=
1answer = numpy.array([0
]*n)
defdfs
(pos,
sum)
:global temp, f
ifsum> m:
return
ifsum
== m:
f =1for i in
range(0
,temp)
:if i == temp-1:
print
(answer[i]
)else
:print
(answer[i],""
,end="")
##按題目要求輸出為一行,所以使用end=「」,取消每次輸出預設的換行符
return
for m in
range
(pos,n)
: answer[temp]
= arr[m]
temp+=
1 dfs(m+1,
sum+arr[m]
)if f:
break
temp-=
1sum=0
for i in
range(0
,n):
sum+=arr[i]
ifsum
< m:
print
("no solution"
)else
: arr =
sorted
(arr,reverse=
false
) dfs(0,
0)ifnot f:
print
("no solution"
)exit(
0)
排序函式:python3自帶排序函式sorted(),引數reverse=false時為公升序,為true時為降序。
滿足題目需求的從一行輸入資料,以空格隔開,單獨使用input是不行的,可以使用str= input().split(" 「) 將輸入的輸出按輸入格式存到字串變數中,然後用for迴圈放入list中,也可以使用map()方法:list(map(int,input().split(」 ")))方法完成用空格隔開的一行輸入,map方法返回的為map物件,想要獲取列表物件就用list(map())即可。
7 68 湊零錢 30分
輸入格式 輸入第一行給出兩個正整數 nnn 104 le 10 4 10 4 是硬幣的總個數,mmm 102 le 10 2 10 2 是韓梅梅要付的款額。第二行給出 nnn 枚硬幣的正整數面值。數字間以空格分隔。輸出格式 在一行中輸出硬幣的面值 v1 v2 vkv 1 le v 2 le cdot...
7 1 湊零錢 30分
8 9 5 9 8 7 2 3 4 1 1 3 5 4 8 7 2 4 3 no solution 動態規劃,先對硬幣價值公升序排序,從左向右依次選取硬幣,對於每個硬幣都有兩種情況,取或不取,當所取硬幣總額等於所需總額時,輸出 因為已經公升序排序,所得的第一組資料就是最小序列 以此進行遞迴。測試點6...
刷題之路 零錢湊整問題
有陣列penny,penny中所有的值都為正數且不重複。每個值代表一種面值的貨幣,每種面值的貨幣可以使用任意張,再給定乙個整數aim 小於等於1000 代表要找的錢數,求換錢有多少種方法。經典的動態規劃問題,首先需要確定狀態,然後疊加即可。首先確定初始狀態,當目標錢數為0時,無論如何只有一種方法,即...