Java 带阈值的最大和子序列
给定一个整数数组,求小于或等于给定阈值的子序列的最大和 承包商:Java 带阈值的最大和子序列,java,arrays,algorithm,recursion,dynamic-programming,Java,Arrays,Algorithm,Recursion,Dynamic Programming,给定一个整数数组,求小于或等于给定阈值的子序列的最大和 承包商: 数组的最大大小为10^5 数组中的元素为10^9时的最大大小 阈值在1到10^9的范围内 e、 g. 输入: 1 2 4 5 十, 输出: 十, 在上面的示例中,数组是[1,2,4,5],阈值是10。最大和子序列为10,由(1,4,5)组成 导入java.util.array; 公共类MaxSumSubsequenceWithThreshold{ 类解决方案{ int[]A; int阈值; 整数[][]dp; 解决方案(int[]
数组的最大大小为10^5
数组中的元素为10^9时的最大大小
阈值在1到10^9的范围内 e、 g.
输入:
1 2 4 5
十, 输出:
十, 在上面的示例中,数组是[1,2,4,5],阈值是10。最大和子序列为10,由(1,4,5)组成
导入java.util.array;
公共类MaxSumSubsequenceWithThreshold{
类解决方案{
int[]A;
int阈值;
整数[][]dp;
解决方案(int[]A,int阈值){
this.A=A;this.threshold=threshold;
dp=新整数[A.length][threshold+1];
}
整数和(整数位置,整数阈值){
如果(threshold为获得更好的性能,我将只循环一次值,并将跟踪TreeSet
中以前的所有总和
作为一个集合
会自动消除重复的总和。例如,如果输入是[1,3,4,7]
,那么当我们处理7时,前面看到的总和将是[1,3,4,1+3,1+4,3,3+4,3+4]=[1,3,4,4,5,7,8]=[1,3,4,5,7,8]
,其中已消除重复总和4
。防止冗余处理
如果我们找到一个等于阈值的和,我们应该停止查找。这称为短循环。如果我们已经找到了最大可能的和,则无需继续查找。例如,如果threshold=8
,我们将跳过7
值的处理,因为我们已经找到了一个等于阈值的和,即1+3+4=8
作为<代码> SoReSETTSE/COD>允许我们找到一个可以添加到当前正在处理的值的子集。例如,如果<代码>阈值= 10 < /代码>,当我们处理<代码> 7 < /代码>时,我们查找<潜在的短路>代码> 3 /代码>,然后只需要考虑范围<代码> 1 < /代码> -<代码> 2 < /代码>中的先前和,因此我们可以调用<代码>t(1,3)
来获取这些
虽然问题没有明确说明,但是我们认为空序列是有效的,这意味着<代码> 0 <代码>是一个有效的结果,如果我们没有找到一个解决方案。这很容易防范
使用上述逻辑,我们不会添加超过阈值的总和。例如,如果阈值=6
,则完成后,上述集合将包含[1,3,4,5]
。然后,我们可以调用last()
来查找最大总和
以下是所有这些的代码:
静态整数最大和(整数阈值,整数…值){
树集和=新树集();
for(int值:值){
如果(值==阈值)
返回阈值;//短路
如果(值<阈值){
if(总和包含(阈值))
返回阈值;//短路
for(int prevSum:sums.subSet(1,阈值).toArray(新整数[0]))
总和。相加(前总和+值);
增加(价值);
}
}
返回(sums.isEmpty()?0:sums.last().intValue());
}
注意:我们不能在迭代子集时添加到和
,因此我们需要子集的副本。toArray()
是获得此类副本的最快方法
测验
System.out.println(最大和(10,1,2,4,5));
系统输出println(最大和(8,1,3,4,7));
系统输出println(最大和(10,1,3,4,7));
系统输出println(最大和(6,1,3,4,7));
系统输出println(最大和(3,5,7,9));
输出
10
8.
10
5.
0
为了获得更好的解决方案,不要使用递归。阈值是否有限制,例如,1在说明中添加了阈值范围。
import java.util.Arrays;
public class MaxSumSubsequenceWithThreshold {
class Solution {
int[] A;
int threshold;
Integer[][] dp;
Solution(int[] A, int threshold) {
this.A = A; this.threshold = threshold;
dp = new Integer[A.length][threshold + 1];
}
int sum(int pos, int threshold) {
if (threshold <= 0) return 0;
if (threshold - A[pos] < 0) return dp[pos][threshold] = Integer.MIN_VALUE;
if (dp[pos][threshold] != null) return dp[pos][threshold];
int sum = 0;
int max = Integer.MIN_VALUE;
for (int i = pos + 1; i < A.length; i++) {
sum = sum(i, threshold - A[pos]);
max = Math.max(max, sum);
}
return dp[pos][threshold] = max == Integer.MIN_VALUE ? A[pos] : max + A[pos];
}
int solve() {
Arrays.sort(A);
int max = Integer.MIN_VALUE;
for (int i = 0; i < A.length; i++) {
dp[i][threshold] = sum(i, threshold);
max = Math.max(max, dp[i][threshold]);
}
return max;
}
}
public static void main(String[] args) {
int[] A = InputUtils.nextIntLine();
int threshold = InputUtils.nextInt();
System.out.println(
new MaxSumSubsequenceWithThreshold().new Solution(A, threshold).solve()
);
}
}