本文內容遵從
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和可以使用的...