贪心算法-给定总额N和不同的面值arr[],找arr[]中面值能够组合从1到N所有值的最小数量

版权声明:转载请标明出处 https://blog.csdn.net/weixin_40661297/article/details/89644723

给定总额N和不同的面值arr[],找arr[]中面值能够组合从1到N所有值的最小数量

分析:贪心算法,

  1. arr[]没有1返回错误
  2. 对arr排序,如【1,3,5,10】,先从最小的面额开始组合(即1),设当前组合能达到的最大金额为M,当M<3-1时,不能用3,还得用1,当M=2(两个1组合)是,M>=3-1,表示3以下的都已经可以组合了,那么现在就可以用3这个面值了,用了3后,M=M+3=5,表示5及5以下的面值都可以组合了(解释:原来两个1可以组合(1,2),现在有了3,就可以组合(1,2,3,4,5)),M此时为5,所以就可以用5这个面值了,那么原来可以组合(1,2,3,4,5)现在这个组合再加上5这个面值,就可以组合(1,2,3,4,5,6,7,8,9,10),依次类推。

代码可返回三种类型
int count = 0; //面值总数
int[]dp1 = new int[sum]; //不同总额下的面值总数
int[]dp2 = new int[arr.length]; //每种面值的个数

package test;

import java.util.Arrays;

public class demo2 {
	public static void main(String[] args) {
		int sum = 10;
		int[] arr = {1,3,5};
		int count = countToSum(arr,sum);
		System.out.println(count);
	}

	/**
	 * @param arr :给定不同的面值
	 * @param sum :给定总额
	 * @return 返回所需要的面值总数
	 */
	private static int countToSum(int[] arr, int sum) {
		// TODO Auto-generated method stub
		if(arr==null||arr.length==0) return 0;
		Arrays.sort(arr);
		if(arr[0]!=1) return 0;
		int curSum = 0;
		int count = 0;                    //面值总数
		int[]dp1 = new int[sum];          //不同总额下的面值总数
		int[]dp2 = new int[arr.length];   //每种面值的个数
		int k = 0;
		int index = 0;
		while(curSum<sum) {
			curSum +=arr[index];
			count++;
			dp2[index]++;
			if(index<arr.length-1&&curSum+1>=arr[index+1]) {
				index++;
			}
			while(k<sum&&k<curSum) {
				dp1[k++] = count;
			}
		}
		System.out.println(Arrays.toString(dp1));
		System.out.println(Arrays.toString(dp2));
		return count;
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_40661297/article/details/89644723