public static List<Integer> limitValSubsequence(int[] sequence, int limitValue) {
List<Integer> retList = new ArrayList<>();
int[] sortSeq = Arrays.copyOf(sequence, sequence.length);
Arrays.sort(sortSeq);
int sumVal = 0;
int k = 0;
for (int i = sortSeq.length - 1; i >= 0; i--) {
sumVal += sortSeq[i];
if (sumVal > limitValue) {
k = sortSeq.length - i;
break;
}
}
if (k == 0) {
System.err.println("No subsequence math condition to > " + limitValue);
return retList;
}
limitValSubsequencePart(sortSeq, k, sequence.length - 1, limitValue, retList);
return retList;
}
public static int limitValSubsequencePart(int[] sequence, int count, int right, int limitValue,
List<Integer> outSeq)
{
outSeq.clear();
if (count <= 0) return Integer.MIN_VALUE; //不可选了
if (right < 0) return Integer.MIN_VALUE;
int curVal = sequence[right];
if (limitValue > count * curVal) return Integer.MIN_VALUE;
if (right == 0) {
if (curVal > limitValue && count == 1) {
outSeq.add(curVal);
return curVal;
} else {
return Integer.MIN_VALUE;
}
}
//if curVal in
List<Integer> curInSeq = new ArrayList<>();
int inValue = Integer.MIN_VALUE; //预设无效
if (curVal > limitValue && count == 1) {
inValue = curVal;
curInSeq.add(curVal);
} else {
List<Integer> inSubSeq = new ArrayList<>();
int subVal = limitValSubsequencePart(sequence, count - 1, right-1, limitValue - curVal, inSubSeq);
if (subVal == Integer.MIN_VALUE) {//无效
inValue = Integer.MIN_VALUE;
} else {
inValue = curVal + subVal;
curInSeq.addAll(inSubSeq);
curInSeq.add(curVal);
}
}
//if curVal not in
List<Integer> curOutSeq = new ArrayList<>();
int outValue = limitValSubsequencePart(sequence, count, right-1, limitValue, curOutSeq);
if (inValue == Integer.MIN_VALUE) {
outSeq.addAll(curOutSeq);
return outValue;
} else if (outValue == Integer.MIN_VALUE) {
outSeq.addAll(curInSeq);
return inValue;
} else {
if (curInSeq.size() < curOutSeq.size()) {
outSeq.addAll(curInSeq);
return inValue;
} else if (curInSeq.size() > curOutSeq.size()) {
outSeq.addAll(curOutSeq);
return outValue;
} else {
if (inValue > outValue) {
outSeq.addAll(curOutSeq);
return outValue;
} else {
outSeq.addAll(curInSeq);
return inValue;
}
}
}
}
public static void testLimitValArray() {
final int NUMBER = 150;
int[] inputs = new int[NUMBER];
for (int i = 0; i < NUMBER; i++) inputs[i] = i+1;
int limitValue = NUMBER * 10;
long startTime = System.currentTimeMillis();
List<Integer> vals = limitValSubsequence(inputs, limitValue);
int sumVal = 0;
for (int val : vals) sumVal += val;
long usedTime = System.currentTimeMillis() - startTime;
System.out.println("testLimitValArray limit:" + limitValue + ", sum:" + sumVal + ", elems:" + vals + ", usedTime:" + usedTime);
}
思路和qq_38843185 是一致的。
testLimitValArray limit:1500, sum:1501, elems:[46, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150], usedTime:9565