大整数分割成 多个小整数问题(二)

问题:

分硬币问题,假设sum代表总的钱数,数组a中的元素代表有的单个硬币,问sum最少需要a中的几个硬币(可以重复)加起来才能得到sum?

比如:

int[] a = {1,10,15,21,25};
int sum = 63;

那么最少就是3个21的才能得到sum

ps:贪婪算法在这个例子中就不成立,所以贪婪方法没有用

算法1:

大整数分割成 多个小整数问题(一)一样,循环每次sum减去a中的有的一个硬币面值,总数就等于这个硬币数(1)+剩下的需要的最小硬币数硬币数,循环每次结果都和最小比较如果更少就更新最小值,边界条件是如果等于0就表明这个构成方法有效,返回0;如果小于0则无效,返回

Integer.MIN_VALUE

最后result为负则不更新最小硬币数值

代码:

public int minCoinNumbers1(int[] a,int sum){
		int result = 0;
		int min = Integer.MAX_VALUE;
		if(sum<0)//小于0就是硬币没有组合成功,返回一个极大负值通过result>0不影响结果判断
			return Integer.MIN_VALUE;
		if(sum==0)//等于0就是硬币一个组合成功,返回0结
							//		束一个递归过程,前面每次递归加的1就是硬币数
			return 0;
		for(int i=0;i<a.length;i++){
			result = 1+minCoinNumbers1(a,sum-a[i]);
			if(result>0&&result<min){                     
				min = result;           
			}
			result = 0;
		}
		return min;
	}

算法2:weiss书中的代码,缺陷就是默认硬币面值为1存在,如果数组a中1不存在算法就会出现问题.

思路是:硬币数等于:

for(int i=1;i<=sum/2;i++){//循环从1开始,从0开始就是sum由0+sum组成的无穷递归
			result = minCoinNumbers2(a,i)+minCoinNumbers2(a,sum-i);
			
		}

这个循环中的最小值。

边界条件是:如果在a数组中存在对应的sum,那就直接返回1表示取这个硬币。

代码如下:

public int minCoinNumbers2(int[] a,int sum){
		int result = 0;
		int min = Integer.MAX_VALUE;
		
		for(int i=0;i<a.length;i++){
			if(sum==a[i]){
				return 1;
			}
		}
		for(int i=1;i<=sum/2;i++){//循环从1开始,从0开始就是sum由0+sum组成的无穷递归
			result = minCoinNumbers2(a,i)+minCoinNumbers2(a,sum-i);
			if(min>result){
				min = result;
			}
			result = 0;
		}
		return min;
	}

    原文作者:大整数乘法问题
    原文地址: https://blog.csdn.net/mingzidaodiduochang/article/details/8050026
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞