java動態規劃取硬幣問題
阿新 • • 發佈:2018-03-15
四種 ava exti 千萬 print light sca 小數 length
最近一直在研究動態規劃的問題。今天遇到了取硬幣問題。
其實動態規劃還是,我從底部向頂部,依次求出每個狀態的最小值,然後就可以標記上。
這道題目就是,假如有1,5,7,10這四種幣值的硬幣,我取14元,取的硬幣數最少要多少張。
其實動態規劃就是要求出狀態轉移方程,就好比我的上一個博客的求最短路徑的問題。而這道取硬幣問題呢。如果我的硬幣大於有的幣值,那麽就能狀態轉移
轉移為temp[i-weizhi[j] + 1。temp[]是用來存放每種幣值的最小數目。weizhi[]是用來存放幣值。比如說吧,temp[0]表示取0個幣值要0次,temp[1] 中1只大於1,所以能取1枚硬幣。那麽轉換成temp[1-1]+1,取1次
temp[2]呢,2也是只大於1,那麽轉化成temp[2-1]+1......到temp[5]就不一樣了,temp[5]中的5大於1,所以可以取temp[5-1]+1 = 5 ,而也可以取temp[5-5]+1 = temp[0]+1 = 0+1 = 1。照這種思想完全可以編出代碼來了。但是這裏涉及到一個問題,我每次都需要比較我最小的一個,這時候直接用變量來存放就行了,千萬別習慣性的想用數組,我開始就是想用數組,但是還越界了,下面是我的代碼,其實那個for循環就是動態規劃的核心。可以理解為填數字吧。今天這麽晚了,明天給大家更新填數字的代碼。
import java.util.Scanner; public class 找零錢 { public static void main(String[] args) { Scanner scn = new Scanner(System.in); System.out.println("請輸入想計算多少枚硬幣:"); int n = scn.nextInt(); int temp[] = new int[n+1]; //存放每種硬幣取的最少的取法 int weizhi[] = {1,5,7,10}; //四種硬幣 //動態規劃的核心,用for循環去填充每次能標記上的 for(int i=1;i<temp.length;i++) { //取的硬幣的數量 int minV = i; //初始化最小的為minV,因為最小取的硬幣數量肯定不會比i還要大 for(int j=0;j<weizhi.length;j++) { if(i>=weizhi[j]) { //取的硬幣的數目比有的數目要大。 int k = temp[i-weizhi[j]] + 1; //狀態轉移方程,前面介紹的。 if(k<minV) { minV = k; //保存了,這一趟比較的最小的取的硬幣值 } } } temp[i] = minV; } System.out.println("至少需要" + temp[n] + "枚硬幣"); } }
java動態規劃取硬幣問題