1. 程式人生 > >java動態規劃取硬幣問題

java動態規劃取硬幣問題

四種 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動態規劃取硬幣問題