今天早上看一位搞cv的高手坯子的部落格,看到了乙個找零問題,覺得蠻有意思的,現分享如下:
現存在一堆面值為 v1、v2、v3 … 個單位的硬幣,問最少需要多少個硬幣才能找出總值為 t 個單位的零錢?假設這一堆面值分別為 1、2、5、21、25 元,需要找出總值 t 為 63 元的零錢。
很明顯,只要拿出 3 個 21 元的硬幣就湊夠了 63 元了。
找63元,如果直接找最大面值,則有25+25+5+5+2+1,明顯不是最小硬幣數,所以直接找最大面值不行。怎樣才能找到21呢?
將問題分解,分別找到63-1,63-2,63-5,63-21,63-25的最小硬幣數,這五個中最小的,一定也就是組成63的最小硬幣數。如果求62需要求61,60,57,41,37, 求61需要求60,59,56,40,36...
用conisused表示每乙個面值對應的最小硬幣數,則: coinsused[i]=coinsused[i-coinvalue]+1;
用coinstrack陣列記錄每乙個面值對應的coinvalue;
可以考慮使用動態規劃方法:
動態規劃的基本思想是將待求解問題分解成若干個子問題,先求解子問題,並將這些子問題的解儲存起來,如果以後在求解較大子問題的時候需要用到這些子問題的解,就可以直接取出這些已經計算過的解而免去重複運算。儲存子問題的解可以使用填表方式,例如儲存在陣列中。
具體**如下:
#include #include using namespace std;
/* @param coinvalue:
儲存硬幣面值的陣列
@param coinsize
儲存面值的種類,即conivalue的大小
@param moneyvalve
需要找零的面值
@param coinsused
記錄每乙個面值所對應的最小硬幣數
@param coinstrack
記錄組成每乙個面值所對應的,使其硬幣數最小所加入的硬幣面值
*/ void makechange(int* coinvalue,size_t coinsize,int moneyvalue,int *coinsused,int *coinstrack)
} int main(int argc, char *argv)
; //硬幣陣列大小
size_t size=sizeof(value)/sizeof(*value);
//要找零的數
int money=45;
//儲存每個面值對應最小值,因為0號位置捨棄,故加1
int* coinsused=new int[money+1];
int* coinstrack=new int[money+1];
makechange(value,size,money,coinsused,coinstrack);
system("pause");
return exit_success;
}
買票找零問題
問題描述 一場激烈足球賽即將開始,售票員緊張地賣票著 每張球票50元,現在有2n 1 n 18 個球迷排隊購票,其中n個手持50元鈔票,另外n個手持100元鈔票。假設開始售票時售票處沒有零錢可以找零。問這2n個人有多少種排隊方式,不至使售票處出現找不出零的局面?例如當n 3時,共6人,3人持50元,...
錢幣找零問題
錢幣找零問題 這個問題在我們的日常生活中就更加普遍了。假設1元 2元 5元 10元 20元 50元 100元的紙幣分別有c0,c1,c2,c3,c4,c5,c6張。現在要用這些錢來支付k元,至少要用多少張紙幣?用貪心演算法的思想,很顯然,每一步盡可能用面值大的紙幣即可。在日常生活中我們自然而然也是這...
錢幣找零問題
題目 假設1元 2元 5元 10元 20元 50元 100元的紙幣分別有c0,c1,c2,c3,c4,c5,c6張。現在要用這些錢來支付k元,至少要用多少張紙幣?用貪心演算法的思想,很顯然,每一步盡可能用面值大的紙幣即可。在日常生活中我們自然而然也是這麼做的。在程式中已經事先將value按照從小到大...