题目
现有资源总量为p,一个数组表示每个任务所需要的资源量。
请输出在优先保证资源分配的最多的情况下任务量最大。
例子:
p=20
arr=[2,8,3,1,9]
输出:
2 8 1 9
解释:2+8+1+9=20,资源可以全部分配
例子:
p=28
arr=[2,8,3,1,4,9]
输出
2,8,3,1,4,9
解释:没有相加可以等于28的组合, 最接近的是所有的和=27
思路
思路就是利用回溯法找所有相加组合中最接近p的组合,如果能等于p那么就取数量最多的那个组合
如果有更有效的思路欢迎指正
代码
import java.util.*;
public class Main {
//资源总量
static int p = 28;
//查询过程中的小于总量的最大值
static int maxVal = 0;
//与最大值对应的list
static List<Integer> resultList = new ArrayList<>();
public static void main(String[] args) {
int[] arr = new int[]{2,8,3,1,4,9};
method(arr,0,0,new ArrayList<Integer>());
System.out.println(resultList);
}
//arr代表数组,i是索引位置,val,list查询过程中累加的值和对应的list
private static void method(int[] arr, int i, int val, ArrayList<Integer> list) {
//分为大于p和等于p
if (val > p){
val -= arr[i-1];
ArrayList<Integer> integers = new ArrayList<>(list);
integers.remove(integers.size()-1);
if (val > maxVal){
maxVal = val;
resultList = integers;
}else if (val == maxVal && integers.size() > resultList.size()){
resultList = integers;
}
return;
}
if (val == p){
if (val > maxVal){
maxVal = val;
resultList = new ArrayList<>(list);
}
if (list.size() > resultList.size()){
resultList = new ArrayList<>(list);
}
return;
}
//如果遍历到最后仍然小于p,把结果加上去
if (i==arr.length && resultList.size() == 0){
maxVal = val;
resultList = new ArrayList<>(list);
}
for (int j = i; j < arr.length; j++) {
val += arr[j];
list.add(arr[j]);
method(arr,j+1,val,list);
val -= arr[j];
list.remove(list.size()-1);
}
}
}
变形
这次我们优先取数量最多的组合里面资源分配最有效的组合。
优先数量,其次是分配效率。