换钱的最少货币数


//换钱的最少货币数
public class getMinCurrency{
	//最少货币
    public static int GetMinCoins01(int[]arr,int aim)
    {
    	if(arr==null||arr.length==0||aim<0)
    	{
    		return -1;
    	}
    	int n=arr.length; //数组的长度
    	int max=Integer.MAX_VALUE;
    	int[][]dp=new int[n][aim+1]; //动态规划表
    	/*
    	dp[i][j]的含义:可以使用任意arr[0...i]货币,组成j所需的最小张数
    	*/
    	for(int j=1;j<=aim;j++)
    	{
    		dp[0][j]=max;
    		if(j-arr[0]>=0&&dp[0][j-arr[0]]!=max)
    		{
    			dp[0][j]=dp[0][j-arr[0]]+1;
    		}
    	}
    	int left=0;
    	for(int i=1;i<n;i++)
    	{
    		for(int j=1;j<=aim;j++)
    		{
    			left=max;
    			if(j-arr[i]>=0&&dp[i][j-arr[i]]!=max)
    			{
    				left=dp[i][j-arr[i]]+1;
    			}
    			dp[i][j]=Math.min(left,dp[i-1][j]);//寻找最小的货币数
    		}
    	}
    	return dp[n-1][aim]!=max?dp[n-1][aim]:-1; //返回右下角的数

    }
    //最少货币(压缩矩阵)
    public static int GetMinCoins02(int[]arr,int aim)
    {
    if (arr == null || arr.length == 0 || aim < 0) {
			return -1;
		}
		int n = arr.length;
		int max = Integer.MAX_VALUE;
		int[] dp = new int[aim + 1];
		for (int j = 1; j <= aim; j++) {
			dp[j] = max;
			if (j - arr[0] >= 0 && dp[j - arr[0]] != max) {
				dp[j] = dp[j - arr[0]] + 1;
			}
		}
		int left = 0;
		for (int i = 1; i < n; i++) {
			for (int j = 1; j <= aim; j++) {
				left = max;
				if (j - arr[i] >= 0 && dp[j - arr[i]] != max) {
					left = dp[j - arr[i]] + 1;
				}
				dp[j] = Math.min(left, dp[j]);
			}
		}
		return dp[aim] != max ? dp[aim] : -1;

    }
    //********************************************
    //原问题的进阶问题
    public static int GetMinCoins03(int[]arr,int aim)
    {
      if (arr == null || arr.length == 0 || aim < 0) {
			return -1;
		}
		int n = arr.length;
		int max = Integer.MAX_VALUE;
		int[][] dp = new int[n][aim + 1];
		for (int j = 1; j <= aim; j++) {
			dp[0][j] = max;
		}
		if (arr[0] <= aim) {
			dp[0][arr[0]] = 1;
		}
		int leftup = 0; // 左上角某个位置的值
		for (int i = 1; i < n; i++) {
			for (int j = 1; j <= aim; j++) {
				leftup = max;
				if (j - arr[i] >= 0 && dp[i - 1][j - arr[i]] != max) {
					leftup = dp[i - 1][j - arr[i]] + 1;
				}
				dp[i][j] = Math.min(leftup, dp[i - 1][j]);
			}
		}
		return dp[n - 1][aim] != max ? dp[n - 1][aim] : -1;

    }
    //进阶问题的压缩矩阵法
    public static int GetMinCoins04(int[]arr,int aim)
    {
      if (arr == null || arr.length == 0 || aim < 0) {
			return -1;
		}
		int n = arr.length;
		int max = Integer.MAX_VALUE;
		int[] dp = new int[aim + 1];
		for (int j = 1; j <= aim; j++) {
			dp[j] = max;
		}
		if (arr[0] <= aim) {
			dp[arr[0]] = 1;
		}
		int leftup = 0; // 左上角某个位置的值
		for (int i = 1; i < n; i++) {
			for (int j = aim; j > 0; j--) {
				leftup = max;
				if (j - arr[i] >= 0 && dp[j - arr[i]] != max) {
					leftup = dp[j - arr[i]] + 1;
				}
				dp[j] = Math.min(leftup, dp[j]);
			}
		}
		return dp[aim] != max ? dp[aim] : -1;

    }

    public static void main(String[]args)
    {
        //原问题
    	//System.out.println("Hello");
        int[] arr1 = { 100, 20, 5, 10, 2, 50, 1 };
		int aim1 = 17019;
		System.out.println(GetMinCoins01(arr1, aim1));
		System.out.println(GetMinCoins02(arr1, aim1));
      
        //进阶问题
		int[] arr2 = { 10, 100, 2, 5, 5, 5, 10, 1, 1, 1, 2, 100 };
		int aim2 = 223;
		System.out.println(GetMinCoins03(arr2, aim2));
		System.out.println(GetMinCoins04(arr2, aim2));
 
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值