版权声明:转载请标明出处 https://blog.csdn.net/weixin_40661297/article/details/89644723
给定总额N和不同的面值arr[],找arr[]中面值能够组合从1到N所有值的最小数量
分析:贪心算法,
- arr[]没有1返回错误
- 对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;
}
}