数组的最佳划分为四个部分
给定一个包含 n 个非负整数的数组。从数组中选择三个索引,即(0 <= index_1 <= index_2<= index_3 <= n)来生成四个子集,使得sum(0, index_1) – sum(index_1, index_2) + sum(index_2, index_3 ) – sum(index_3, n)是可能的最大值。
这里,两个索引说 l 和 r 意味着 sum(l, r) 将是从 l 到 r 不包括在内的位置上的所有子集数的总和(不计算第 l 个元素,计算第 r 个元素)。例如,如果 arr = {-5, 3, 9, 4},则 sum(0, 1) = -5, sum(0, 2) = -2, sum(1, 4) = 16 和 sum(i , i) = 0 对于从 0 到 4 的每个 i。对于索引 l 和 r 保持 0 <= l <= r <= n。数组中的索引从 0 开始编号。
例子:
Input : arr = {-1, 2, 3}
Output : 0 1 3
Here, sum(0, 0) = 0
sum(0, 1) = -1
sum(1, 3) = 2 + 3 = 5
sum(3, 3) = 0
Therefore , sum(0, 0) - sum(0, 1) + sum(1, 3) - sum(3, 3) = 4
which is maximum.
Input : arr = {0, 0, -1, 0}
Output : 0 0 0
Here, sum(0, 0) - sum(0, 0) + sum(0, 0) - sum(0, 0) = 0
which is maximum possible.
想象一下相同的任务,但总和没有第一项。由于数组的总和是固定的,因此最好的第二段应该是总和最大的段。这可以用前缀总和在 O(n) 中解决。当调用在位置 i 处结束的最佳段时,取从 0 到 i 的最小前缀总和(从要减去最小数字的总和中)。
现在让我们遍历第一个段的所有可能末端,并在没有这个段的数组上解决上面的任务。
C++
// CPP program to find three indices
#include
#define max 50009
using namespace std;
// Function to find required indices.
void find_Indices(int arr[], int n){
int sum[max], k;
int index_1, index_2, index_3, index;
// calculating prefix sum from
// 1 to i for each i.
for (int i = 1, k = 0; i <= n; i++)
sum[i] = sum[i-1] + arr[k++];
long long ans = -(1e15);
index_1 = index_2 = index_3 = -1;
// iterating the loop from 0 to n
// for all possibilities.
for (int l = 0; l <= n; l++) {
int index = 0;
long long vmin = (1e15);
// Here, we recalling the best
// segment to end at position i.
for (int r = l; r <= n; r++) {
// taking the minimal prefix
// sum from 0 to i inclusive.
if (sum[r] < vmin) {
vmin = sum[r];
index = r;
}
// calculating the indices.
if (sum[l] + sum[r] - vmin > ans)
{
ans = sum[l] + sum[r] - vmin;
index_1 = l;
index_2 = index;
index_3 = r;
}
}
}
// Required indices.
printf("%d %d %d", index_1, index_2, index_3);
}
// Driver function
int main() {
int arr[] = {-1, 2, 3};
int n = sizeof(arr)/sizeof(arr[0]);
find_Indices(arr, n);
}
Java
// Java program to find three indices
class GFG {
static final int max = 50009;
// Function to find required indices.
static void find_Indices(int arr[], int n)
{
int sum[] = new int[max];
int index_1, index_2, index_3, index;
int k, i;
// calculating prefix sum from
// 1 to i for each i.
for (i = 1, k = 0; i <= n; i++)
sum[i] = sum[i - 1] + arr[k++];
double ans = -(1e15);
index_1 = index_2 = index_3 = -1;
// iterating the loop from 0 to n
// for all possibilities.
for (int l = 0; l <= n; l++) {
index = 0;
double vmin = (1e15);
// Here, we recalling the best
// segment to end at position i.
for (int r = l; r <= n; r++) {
// taking the minimal prefix
// sum from 0 to i inclusive.
if (sum[r] < vmin)
{
vmin = sum[r];
index = r;
}
// calculating the indices.
if (sum[l] + sum[r] - vmin > ans)
{
ans = sum[l] + sum[r] - vmin;
index_1 = l;
index_2 = index;
index_3 = r;
}
}
}
// Required indices.
System.out.print(index_1 + " " + index_2 +
" " + index_3);
}
// Driver function.
public static void main(String[] args)
{
int arr[] = { -1, 2, 3 };
int n = arr.length;
find_Indices(arr, n);
}
}
// This code is contributed by Anant Agarwal.
Python3
# Python program to
# find three indices
max = 50009
# Function to find
# required indices.
def find_Indices(arr, n):
sum=[0 for i in range(max)]
# calculating prefix sum from
# 1 to i for each i.
k=0
for i in range(1,n+1):
sum[i] = sum[i-1] + arr[k];
k+=1
ans = -(1e15)
index_1 = index_2 = index_3 = -1
# iterating the loop from 0 to n
# for all possibilities.
for l in range(n+1):
index = 0
vmin = (1e15)
# Here, we recalling the best
# segment to end at position i.
for r in range(l,n+1):
# taking the minimal prefix
# sum from 0 to i inclusive.
if (sum[r] < vmin):
vmin = sum[r]
index = r
# calculating the indices.
if (sum[l] + sum[r] - vmin > ans):
ans = sum[l] + sum[r] - vmin
index_1 = l
index_2 = index
index_3 = r
# Required indices.
print(index_1," ", index_2," ", index_3)
# Driver function
arr = [-1, 2, 3]
n = len(arr)
find_Indices(arr, n)
# This code is contributed
# by Anant Agarwal.
C#
// C# program to find three indices
using System;
class GFG {
static int max = 50009;
// Function to find required indices.
static void find_Indices(int []arr, int n)
{
int []sum = new int[max];
int index_1, index_2, index_3, index;
int k, i;
// calculating prefix sum from
// 1 to i for each i.
for (i = 1, k = 0; i <= n; i++)
sum[i] = sum[i - 1] + arr[k++];
double ans = -(1e15);
index_1 = index_2 = index_3 = -1;
// iterating the loop from 0 to n
// for all possibilities.
for (int l = 0; l <= n; l++) {
index = 0;
double vmin = (1e15);
// Here, we recalling the best
// segment to end at position i.
for (int r = l; r <= n; r++) {
// taking the minimal prefix
// sum from 0 to i inclusive.
if (sum[r] < vmin)
{
vmin = sum[r];
index = r;
}
// calculating the indices.
if (sum[l] + sum[r] - vmin > ans)
{
ans = sum[l] + sum[r] - vmin;
index_1 = l;
index_2 = index;
index_3 = r;
}
}
}
// Required indices.
Console.WriteLine(index_1 + " " + index_2 +
" " + index_3);
}
// Driver function.
public static void Main()
{
int []arr = { -1, 2, 3 };
int n = arr.Length;
find_Indices(arr, n);
}
}
// This code is contributed by vt_m.
PHP
$ans)
{
$ans = $sum[$l] +
$sum[$r] - $vmin;
$index_1 = $l;
$index_2 = $index;
$index_3 = $r;
}
}
}
// Required indices.
echo($index_1." ".$index_2.
" ".$index_3." ");
}
// Driver Code
$arr = array(-1, 2, 3);
$n = count($arr);
find_Indices($arr, $n);
// This code is contributed by
// Manish Shaw(manishshaw1)
?>
Javascript
输出:
0 1 3
时间复杂度: