DP 换硬币问题

设有n种不同面值的硬币,现要用这些面值的硬币来找开待凑钱数m,可以使用的各种面值的硬币个数不限。
   找出最少需要的硬币个数,并输出其币值。



 

package DP;

import java.util.Arrays;

/**
 * A country has coins with denominations
 * 1 = d1 < d2 < · · · < dk.
 * 
 * You want to make change for n cents, using the smallest number
 */
public class CoinChange {

	public static int MEM[] = new int[10001];   // Can support up to 10000 peso value
    public static int coins[] = {1, 2, 3};  // Available coin denominations
     
    public static void main(String[] args) {
        
    	int n = 321;
        
        System.out.println(CC(n) + ", " + CC_DP(n));
    }
    
    // 记忆化搜索,top-down 递归
    public static int CC(int n) {
        if(n < 0)
            return Integer.MAX_VALUE -1;
        else if(n == 0)
            return 0;
        else if(MEM[n] != 0)    // If solved previously already
            return MEM[n];
        else {
            // Look for the minimal among the different denominations
            MEM[n] = 1+CC(n-coins[0]);
            for(int i = 1; i < coins.length; i++)
                MEM[n] = Math.min(MEM[n], 1+CC(n-coins[i]));
            return MEM[n];
        }
    }

    // bottom-up DP
	public static int CC_DP(int n){
		int[] minCoins = new int[n+1];
		Arrays.fill(minCoins, Integer.MAX_VALUE);
		
		// 第一个硬币
		minCoins[0] = 0;
		
		// 算出n前的每一个可换硬币的数量
		for(int i=1; i<=n; i++){
			// 根据递推公式,看看硬币可拆分的可能性
			for(int j=0; j<coins.length; j++){
				if(coins[j] <= i){
					minCoins[i] = Math.min(minCoins[i], 1+minCoins[i-coins[j]]);
				}
			}
		}
		
		return minCoins[n];
	}
	
}


 



 

posted @ 2013-10-31 21:42  pangbangb  阅读(477)  评论(0编辑  收藏  举报