最少硬幣問題

2021-05-10 16:57:50 字數 1581 閱讀 2294

本文內容遵從

cc版權協議

設有n 種不同面值的硬幣,各硬幣的面值存於陣列t[1:n]中。現要用這些面值的硬幣來找錢。可以使用的各種面值的硬幣個數與面值分別存於陣列coin[1:n]和t[1:n]中。對任意錢數0≤m≤20001,設計乙個用最少硬幣找錢m的方法,對於給定的1≤n≤10,硬幣面值陣列t和可以使用的各種面值的硬幣個數陣列coins,以及錢數m,0≤m≤20001,程式設計計算找錢m的最少硬幣數。由檔案input.txt 提供輸入資料,檔案的第一行中只有1 個整數給出n的值,第2 行起每行2 個數,分別是t[j]和coins[j]。最後1 行是要找的錢數m。

我們可以先把此問題簡化,不限制各類硬幣的使用個數,問最少需要多少硬幣。錢數i的最少需要多少個硬幣怎麼推出來呢?我們可以得到乙個必然的結論:如果存在最小值,數值為i的最少硬幣數必定為數值為j(j 然而我們對錢個數進行限制後,此方程就不能再使用了,因為有時候我們達到最小值用了2個5,卻只提供1個5,1個2,1個3,這時候我們所需的另乙個5就需要從1個2,1個3替代得到。我們對條件進行限制後,問題並沒有得到簡單,而是變得更難了。

既然對錢數進行了限制,上面那個遞推方程就不能再使用了,然而我們還是可以從其中得到很多有用的資訊,f[i] = min(f[i – coin[k] ] + 1, f[i]),看起來只使用了coin[k]一次,但f[i – coin[k]]也可能使用了coin[k]來得到最優值,那麼coin[k]最多可能被使用i / coin[k]次。我們所需要做的就是限制這個i / coin[k]使它不大於限定的次數。

我們可以一次一次的向最優值上面累加coin[k],並且累加的次數不大於給定的次數即可。這時候仍存在乙個問題,就是遞推需要從後往前推,因為每次都是更次後面的值(如果使用二維數就不存在這類問題)。問題順利解決。

#include

#include

using

namespace

std;

#define maxm 20002

#define maxn 10

intcoins

[maxn

];intt[

maxn

];intf[

maxm

];int

m, n;

intmincoin(

int n

,int

m) f[

0]=0;

for(

inti=

0; i

< n;

++i) }}

}if(

f[m]

>

m)

else

}int

main()

scanf(

"%d",&

m);

intans

=mincoin(n

,m);

printf(

"%d/n"

,ans);

return

0; }

還有一類與此問題非常類似的叫做整數分拆。有興趣的可以去維基百科看看。下面給出**:http://zh.wikipedia.org/zh-cn/%e6%95%b4%e6%95%b8%e5%88%86%e6%8b%86

最少硬幣問題

問題描述 有n種不同面值的硬幣,各硬幣面值存於陣列t 1 n 現用這些面值的錢來找錢 各面值的個數存在陣列num 1 n 中。程式設計任務 對於給定的1 n 10,硬幣面值陣列 各面值的個數及錢數m,0 m 2001,程式設計計算找錢m的最少硬幣數。input 第乙個數字n,後面n行每行兩個數,面值...

最少硬幣問題

問題描述 設有n 種不同面值的硬幣,各硬幣的面值存於陣列t 1 n 中。現要用這些面值的硬 幣來找錢。可以使用的各種面值的硬幣個數存於陣列coins 1 n 中。對任意錢數0 m 20001,設計乙個用最少硬幣找錢m的方法。程式設計任務 對於給定的1 n 10,硬幣面值陣列t和可以使用的各種面值的硬...

最少硬幣問題

problem description 設有n種不同面值的硬幣,各硬幣的面值存於陣列t 1 n 中。現要用這些面值的硬幣來找錢。可以使用的各種面值的硬幣個數存於陣列coins 1 n 中。對任意錢數0 m 20001,設計乙個用最少硬幣找錢m的方法。對於給定的1 n 10,硬幣面值陣列t和可以使用的...