【JAVA】连续区间最大和(Pro20210806)(DP)

这是一篇关于如何使用Java解决寻找数组中除指定区间外连续子数组最大和的问题的文章。通过动态规划和区间最大值存储策略提高算法效率。
摘要由CSDN通过智能技术生成

【JAVA】连续区间最大和(Pro20210806)(DP)

题目

假设 A[1…N] 是包含 N 个整数的数组。对数组发出 Q 个请求,每个请求都是一个索引对 (i, j),(每个请求都满足 i ≤ j)。对每个请求的回复是数组 A[1…N] 中除了 i 到 j 的区段之外的最大部分和(数组的连续子数组中和最大的值)。最大子数组至少要包含一个元素。

最大子数组的和是存在于 i 元素左边或者 j 元素右边的元素之和。
各个请求是独立的。也就是说,在一个请求中排除的区段不会影响到后续的请求。

以如下所示的数组为例,整个数组的最大连续子数组的和为 10(从第 3 个元素一直加到第 6 个元素)。

3, -5, 4, -2, 5, 3, -2, 1

如果发出一个请求 (4, 5),那么就要排除第 4 和第 5 个元素。最大子数组要么在第 4 个元素左侧的区段,要么在第 5 个元素右侧的区段。此时,仅包含左边第三个元素 4 时,子数组之和最大。

给定数组和请求,编写程序,计算所有请求的结果之和。

[限制条件]

  1. 数组包含的元素个数 N 介于 2 到 300,000 之间。
  2. 请求数量 Q 介于 1 到 300,000 之间。
  3. 数组中每个元素的值介于 -108 到 108 之间。

[输入]
在第一行给定测试用例数量 T。然后给定 T 种测试用例情况。在每个测试用例的第一行,给定数组包含的元素个数 N 和请求数量 Q,以空格分隔。接下来一行,给定 N 个元素的值(从第 1 个到第 N 个),以空格分隔。接下来 Q 行,每行给定一个请求的索引对 i 和 j,以空格分隔。

[输出]
按标准格式输出每个测试用例的答案。每个测试用例,都输出“#x”(x 为测试用例的编号,从 1 开始,不要引号),加一个空格,然后输出每个测试用例的答案。

[输入和输出示例]
(输入)
3
8 3
3 -5 4 -2 5 3 -2 1
4 6
1 3
3 6
2 2
100000000 -100000000
1 1
2 2
10 5
-9 2 -3 -4 5 6 -7 8 -1 -10
3 8
8 9
2 9
8 8
5 9

(输出)
#1 15
#2 0
#3 17

思路

题目概述:长度为N的整数数组,使用 i、j 分成三段([0, i - 1]、[i, j]、[j + 1]),求第一、三段中的连续区间最大和。

求出以下两个中间值:
以 DATA[n] 元素结尾的连续区间最大和 SUM_A:f(n) = Max( f(n-1) + DATA[n], DATA[n]),即:若 f(n-1) > 0,则 f(n) = f(n-1) + DATA(n),反之f(n) = DATA[n];

以 DATA[n] 元素打头的连续区间最大和 SUM_B:f(n) = Max( f(n+1) + DATA[n], DATA[n]),即:若 f(n+1) > 0,则 f(n) = f(n+1) + DATA(n),反之f(n) = DATA[n];

则可以使用IndexTree,第一段中的连续区间最大和 MAX_L = queryMax(SUM_A, 0, i - 1),第三段中的连续区间最大和 MAX_R = queryMax(SUM_B, j + 1, N - 1)。

那么ASW += Max(MAX_L, MAX_R),累加结果即为所求。

又因为两段查询区间比较特殊,第一段的起点下标为 [0],第三段结束下标为 [N - 1]。
那么将使用IndexTree来提升效率的思路,转化为区间最大值直接存储的方式,即:
将数组 SUM_A、SUM_B 处理的到 MAX_A、MAX_B:
MAX_A[i]中存放的是在SUM_A中,下标在[0, i]区间内的最大值:f(n) = Max(MAX_A[n - 1], SUM_A[n]);
MAX_B[i]中存放的是在SUM_B中,下标在[i, N - 1]区间内的最大值:f(n) = Max(MAX_A[n + 1], SUM_B[n]);

则,第一段中的连续区间最大和 MAX_L = MAX_A[i - 1],第三段中的连续区间最大和 MAX_R = MAX_A[j + 1]。

代码

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
   
	static int T, N, Q, L, R;
	static
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值