动态规划练习三:换钱问题(动态规划概念理解与记忆搜索法概念理解对比)
題目描述
給定數組arr,數組中所有的值都為正數,且不為空不重復。數組中每個數代表一種貨幣的面值,每種面值的貨幣可以使用任意張,然后,給一個aim,代表要換錢的面值,請問,用數組中的面值換錢,總共有多少種方式?
暴力遞歸思路
遞歸的第一步,將問題劃分為更小的子問題,比如,數組arr[1,5,10]這三種面值的貨幣,aim=1000。首先,可以先取出第一種面值。假如,第一種1元的有0張,那么問題就劃分為arr=[5,10],aim=1000;如果第一種1元的有1張,問題就劃分為arr=[5,10],aim=999。依此類推,直到第一種貨幣的面值一元有1000張時,也就是超過aim,那么,第一種的所有結果都例舉出來了。
因此,從上面分析中抽象出遞歸函數。首先,遞歸函數需要記錄arr,和目前是第幾種貨幣面值,也就是數組的索引,其次,還需要記錄aim,當aim為0時,就找到一種換錢方法。
遞歸的出口是,數組遍歷完最后一個,此時aim恰好為0,說明找到一個換錢方法,不為零,就不是,當然,不對的情況包含aim大于和小于的情況。
遞歸方法,就是設定一個res記錄當前符合的換錢方式,遇到出口就返回1或0,否則,就繼續向下遞歸。
遞歸代碼
記憶搜索法
暴力遞歸時間復雜度高的根本原因,就是存在大量的重復操作,而重復操作之所以大量發生,是因為在遞歸的過程中,很多重復計算的結果沒有記錄下來,才會導致重復計算。
因此,記憶搜索法其實也很簡單,就是把每一步遞歸的結果放入一個map中,然后每次遞歸前,先檢查map中有沒有,如果已經有結果,直接取出來,就不需要重復計算了。
動態規劃法
第一步,判斷是否可行?本題中間遞歸結果是不依賴前面的路徑的,因此可行。
第二步,畫圖,找出遞歸過程的變化量,index和aim,畫圖。
第三步,標記結果位置,此題的結果位置為index0,aim1000。
第四步,填入已知數據,已知數據為indexarr.length這一行,aim0的位置填返回值1,其他都是0。
第五步,根據已知結果,結合遞歸函數,我們已知了最后一行indexarr.length的結果,就可以根據遞歸函數,推出indexarr.length-1這一行的結果,然后依次填完表格,直到找到index0,aim1000位置的結果,就是返回的最終結果。
動態規劃和記憶搜索對比
其實,動態規劃可以理解為就是記憶搜索法 。
記憶搜索法不關心到達某一個遞歸過程的路徑,只是單純的記錄遞歸過程的每個結果,避免重復計算。
動態規劃是通過表格來表示每個遞歸過程之間的順序,每個過程依賴前面已知的結果,其實也是在記錄前面的遞歸結果,避免重復計算,只不過是也同時保留了遞歸順序之間的過程。
兩者都是空間換時間的優化思想,區別在于,動態規劃記錄計算順序,而記憶搜索法只是簡單避免重復計算,不記錄計算順序。
因此總結一下,什么動態規劃?
其本質就是利用申請的額外空間來記錄每一個暴力遞歸的結果,下次要用的時候可以直接使用,并且記錄每種遞歸狀態之間的計算順序,依次計算。
總結
以上是生活随笔為你收集整理的动态规划练习三:换钱问题(动态规划概念理解与记忆搜索法概念理解对比)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android——一个简单的闹钟APP
- 下一篇: 为了理想,因为爱情-开课第一天有感(鸡汤