從1元、2元和5元的鈔票和等於100元的演算法問題談到遞迴
引入
一直以來,遞迴思想成為不少新手的攔路虎。同樣作為一個新手,我希望這篇文章可以從新手
的角度出發,走入遞迴。
如本文標題,相信不少人碰到過這個問題:
“現有面值為1元、2元和5元的鈔票(假設每種鈔票都足夠多),從這些鈔票中取出任意張數使
其總面值為100元,問有多少種取法?“
我們將從這個問題入手,逐步深入。
基本思路
本文我們要學習遞迴思想,因此對其他解法不作解釋。一:先簡化題目
將題中100元改成10元,即 ”現有面值為1元、2元和5元的鈔票(假設每種鈔票都足夠多),從這些 鈔票中取出任意張數使其總面值為10元,問有多少種取法“ 以便於我們具體分析; 二:思路(希望大家可以跟著我的思路走)
基本規則: 1、每次只取一張鈔票,面額小的優先。
2、當已取鈔票總額等於或超過10,則停止取鈔,進行相應的判斷後選擇下一步的策略。3、每次取出的面值必須比放回的鈔票大。4、每次取的面值必須大於或等於已取的面值。
現在我們開始去鈔票,根據規則1,每次只取一張,我們從面額最小的開始取(面值小優先):第一張:取1元;第二張:取1元;第三張:取1元;
...第九張:取1元;第十張:取1元;此時已取鈔票總額為10元,根據規則2,停止取鈔,進行判斷。(11111 11111)
1.我們發現手裡的鈔票總額剛好為10,取法數N變為1;
2.然後我們將最後(即第十張)取出的那張1元鈔票放回未取鈔票中,根據規則3,選擇
一張面額為2的鈔票放入手中;此時已取鈔票總額為11元,根據規則2,停止取鈔,進行判斷。(11111 11112)
1.我們發現手裡的鈔票總額為11,取法數N不變;
2.然後我們將最後取出的那張2元鈔票放回未取鈔票中,根據規則3,選擇一張面額為5的
鈔票放入手中;此時已取鈔票總額為14元,根據規則2,停止取鈔,進行判斷。(11111 11115)
1.我們發現手裡的鈔票總額為14,取法數N不變;
2.然後我們將最後取出的那張5元鈔票放回未取鈔票中,並且此時已沒有比5面值更大的鈔票選擇,因此我們的策略是:將此刻手中的最後取出(即第九張)的那張1元鈔票放回
未取鈔票中,根據規則3,再選擇一張面額為2的鈔票放入手中;此時已取鈔票總額為10元,根據規則2,停止取鈔,進行判斷。(11111 1112)1.我們發現手裡的鈔票總額為10,取法數N變為2;
2.然後我們將最後取出的那張2元鈔票放回未取鈔票中,根據規則3,再選擇一張面額為5
的鈔票放入手中;此時已取鈔票總額為13元,根據規則2,停止取鈔,進行判斷。(11111 1115)
1.我們發現手裡的鈔票總額為13,取法數N不變;
2.然後我們將最後取出的那張5元鈔票放回未取鈔票中,並且此時已沒有比5面值更大的
鈔票選擇,因此我們的策略是:將此刻手中的最後取出(即第八張)的那張1元鈔票放回
未取鈔票中,根據規則3,再選擇一張面額為2的鈔票放入手中;此時已取鈔票總額為9,根據規則4,因此取出一張面額為2的鈔票。
此時已取鈔票總額為11元,根據規則2,停止取鈔,進行判斷。(11111 11122)
1.我們發現手裡的鈔票總額為11,取法數N不變;
2.然後我們將最後取出的那張2元鈔票放回未取鈔票中,根據規則3,再選擇一張
面額為5的鈔票放入手中;此時已取鈔票總額為14元,根據規則2,停止取鈔,進行判斷。(11111 11125)
1.我們發現手裡的鈔票總額為11,取法數N不變;
2.然後我們將最後取出的那張5元鈔票放回未取鈔票中,並且此時已沒有比5面值更大的
鈔票選擇,因此我們的策略是:將此刻手中的最後取出那張2元鈔票放回未取鈔票中,
根據規則3,再選擇一張面額為5的鈔票放入手中;此時已取鈔票總額為12,根據規則2,停止取鈔,進行判斷。(11111 115)
1.我們發現手裡的鈔票總額為12,取法數N不變;
2.然後我們將最後取出的那張5元鈔票放回未取鈔票中,並且此時已沒有比5面值更大的
鈔票選擇,因此我們的策略是:將此刻手中的最後取出那張(第七張)1元鈔票放回
未取鈔票中,根據規則3,再選擇一張面額為2的鈔票放入手中;此時已取鈔票總額8,根據規則4,因此取出一張面額為2的鈔票。
此時已取鈔票總額為10元,根據規則2,停止取鈔,進行判斷。(11111 122)
1.我們發現手裡的鈔票總額為10,取法數N變為3;
2.然後我們將最後取出的那張2元鈔票放回未取鈔票中,根據規則3,再選擇一張
面額為5的鈔票放入手中;(以此類推)
..
整個過程,手中鈔票的變化過程如下
以下為原始碼:現有面值為1元、2元和5元的鈔票(假設每種鈔票都足夠多),從這些鈔票中取出
任意張數使其總面值為10元,問有多少種取法?N=10
#include <stdio.h>
int num=0;
void zuhe(int min,int sum)
{
int i;
if(sum==10)
num++;
if(sum>10)
return;
for(i=min;i<6;)
{
if(i==1)
{
zuhe(1,sum+1);
i=2;
}
else if(i==2)
{
zuhe(2,sum+2);
i=5;
}
else
{
zuhe(5,sum+5);
i=6;
}
}
}
int main()
{
int sum=0;
int min=1;
zuhe(min,sum);
printf("%d",num);
}
相關推薦
從1元、2元和5元的鈔票和等於100元的演算法問題談到遞迴
引入 一直以來,遞迴思想成為不少新手的攔路虎。同樣作為一個新手,我希望這篇文章可以從新手 的角度出發,走入遞迴。 如本文標題,相信不少人碰到過這個問題:“現有面值為1元、2元和5元的鈔票(假設每種鈔票都足夠多),從這些鈔票中取出任意張數使 其總面值為100元,問
C#練習 找零,人民幣有100元、50元、10元、5元、2元和1元六種,最少需要準備多少張人民幣
Console.WriteLine("輸入工資"); int money = Convert.ToInt32(Console.ReadLine()); i
4.2.3 程式設計題《將一筆錢換算成1分、2分和5分的硬幣組合》
將一筆錢(大於8分,小於1元,精確到分)換算成1分、2分和5分的硬幣組合。輸入金額,問有幾種換算方法?要求每種硬幣至少有一枚。【輸入形式】從鍵盤輸入一個正整數n。【輸入輸出樣例1】(下劃線部分表示輸入)Input money: 10count=2【樣例說明】輸入提示符後要加一
Java-編譯後出現$1.class、$2.class等多個class文件
etc 多個 cte 結果 rda this bject row temp 部署代碼的時候,由於自身技術不精和疏忽,導致查詢數據沒有正常顯示, 排除法最後只能是放置部署文件時未包括多出來的$class文件。放上去之後果然好使了,才記錄下這個問題。。。 這是因為在我們寫的類中
阿里巴巴中國總裁葉朋 B2B從1 0向2 0的升級 閱讀整理
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
HGDB4.3.2在RHEL7.5中安裝和解除安裝指導手冊
目錄 文件用途 詳細資訊 相關文件 文件用途 介紹HGDB4.3.2在RHEL7.5系統上的圖形化安裝和解除安裝流程。 詳細資訊 1.安裝版本及注意事項 1.1 安裝版本 作業系統 Redhat 7.5 x86_64
兩種配置Servlet的IP地址對映:1註解、2配置檔案
1.建立專案 建立 servlet_test 動態web專案。 建立時點選 next, 勾選如下: 2.建立 test.java類 test.java 內容: 第一種:註解 – 設定IP地址對映
python初始化list列表(1維、2維)
修改 但是 init 二維數組 方法 for range row lis 1.初始化遞增的list: list1 = list(range(10))#print list1#[0,1,2,...,9] 2.初始化每項為0的一維數組: list2 = [0] * 5#prin
把一元錢換成1分,2分,5分的硬幣。有多少種換法
#include<stdio.h> main() { int a,b,c,cnt=0; for(a=0;a<=100;a++){ for(b=0;b<=50;b++){ for(c=
【NOI】1755:菲波那契數列/ 2.2基本演算法之遞迴和自呼叫函式
傳送門:檢視 1755:菲波那契數列總時間限制: 1000ms 記憶體限制: 65536kB 描述 菲波那契數列是指這樣的數列: 數列的第一個和第二個數都為1,接下來每個數都等於前面2個數之和。 給出一個正整數a,要求菲波那契數列中第
【NOI】1696:逆波蘭表示式/ 2.2基本演算法之遞迴和自呼叫函式
傳送門:檢視 1696:逆波蘭表示式 總時間限制: 1000ms 記憶體限制: 65536kB 描述 逆波蘭表示式是一種把運算子前置的算術表示式,例如普通的表示式2 + 3的逆波蘭表示法為+ 2 3。逆波蘭表示式的優點是運算子之間
從遞迴版歸併排序演算法看遞迴函式連續兩次呼叫自己函式每步如何返回,看遞迴和棧的關係
這個題目牽涉問題比較多,主要涉及幾個關鍵詞:遞迴函式,棧,歸併排序演算法(這裡使用遞迴實現),呼叫和返回。 首先解釋一下關鍵詞。1、遞迴函式是直接呼叫自己或通過一系列的呼叫語句間接地呼叫自己的函式。遞迴函式必須至少有一個退出條件,即不再繼續呼叫自己而是返回
把1-9這9個數字按從小到大的順序排列 ,中間添上“+”和"-","",可以計算的結果等於100的程式
Talk is cheap,show me the code~ 窮舉法 計算次數 3^8 = 6561,輸出等於100的結果 arr = {1,2,3,4,5,6,7,8,9} fla
(C語言版)二叉樹遍歷演算法——包含遞迴前、中、後序和層次,非遞迴前、中、後序和層次遍歷共八種
#include <stdlib.h> #include <stdio.h> #include "BiTree.h" #include "LinkStack.h" #include "LinkQueue.h" //初始化二叉樹(含根節點) void InitBiTree(pBiTr
NOI2.2基本演算法之遞迴和自呼叫函式 全排列 分析----如何寫全排列函式
一、題目描述 總時間限制: 1000ms 記憶體限制: 65536kB 描述給定一個由不同的小寫字母組成的字串,輸出這個字串的所有全排列。 我們假設對於小寫字母有'a' < 'b' < ... < 'y' < 'z',而且給定的字串中的字母已經按
樹的前、中、後序遍歷演算法(遞迴與非遞迴)、層序遍歷
二叉樹層次遍歷 非遞迴 void LevelOrder(Tree* T) { if(T == nullptr) return ; queue<Tree *> myqueue; myqueue.push(T); while(!myqueu
PHP無限級樹形結構演算法(遞迴和引用)
測試陣列 $array = [ ['id' => 1, 'pid' => 0, 'name' => '這是主類'], ['id' => 2, 'pid' => 0, 'name' => '這是主類'], ['id' =>
python演算法和資料結構筆記--漢諾塔問題超詳細遞迴過程圖解(堆疊資料結構)
兩個盤子時:1移動到B,2移動到A,1移動到C N個盤子時:n-1移動到B,n移動到A,n-1移動到C 3個盤子為例子,如何將問題歸納為同類的子問題 我們的目標是的第一步先將1,2號盤子移動到B 當3號盤不存在,把B,C柱換個位置,問題轉化為將2個盤子藉助C移動到B子的問題。 要將1,2
[OpenJudge] 2.3基本演算法之遞迴變遞推 PKU2506Tiling
一、原題 9273:PKU2506Tiling 總時間限制: 2000ms 單個測試點時間限制: 1000ms 記憶體限制: 131072kB描述 對於一個2行N列的走道。現在用1*2,2*2的磚去鋪
二叉樹遍歷演算法(遞迴實現先序中序和後續遍歷)(非遞迴實現中序和先續)
二叉樹遍歷 這兩天抓緊把二叉樹遍歷複習了一遍,遞迴實現還是一如既往地簡潔,迭代版本寫了好久還是隻實現了先序和中序,後續一直沒搞明白,有空了再更新。 遞迴實現 void RecursionBackTree(TreeNode * root) {