Problem Description:
X[i], a sequence of successive sequences called X[i] from any number x[a] to X[b] (a<=b),
X[i] The sequence and of the subsequence of the subsequence called X[i].
Now known sequence x[i], ask some questions about the maximum sequence and answer.
One, the sub-sequence of the most large
"Method One"
Simple search, using s[i]=s[0]+...+s[i]
Perform an O (n^2) lookup and compare S[i]-s[j] (i>j)
The maximum value, which is the answer
Code
Slightly
"Scope of Application"
Need to visually understand the maximum sequence and start and end positions
"Method Two" see Supplement "need to request sequence position" "divide"
"Method Three""not for sequential position" "Dynamic planning"
Data structure
int LMAX[MAXN]
Code
Lmax[0] = x[0];
for (int i=1; i<n; i++)
if (lmax[i-1]<=0)
Lmax[i]=x[i];
Else
LMAX[I]=LMAX[I-1] + x[i];
/*
* In the case of known lmax[i-1] as the maximum sub-sequence containing x[i-1],
* If LMAX[I-1] is negative, then x[i] must be greater than lmax[i-1], so lmax[i]=x[i]
* If LMAX[I-1] is non-negative, then x[i]+lmax[i-1] must be greater than x[i] or other sequence up to X[i], so lmax[i]=x[i]+lmax[i-1]
*/
Two, the most large and the twin series
"Double" The word is very strange, see "Double", it must be a strange technique can be used.
Note that the double here means that there are at least 1 unit-length intervals between the two sub-sequences.
So it's natural to think of a scenario like this:
Yes, the ordinary algorithm can certainly write, but the complexity must be not low,
So if you want to reduce complexity, the breakthrough of the program is at the gap.
Set the notch length to 1 and position K
the left sequence in the diagram is S_left=∑ ▒ X[i] (i=1..k-1)
make the sequence on the right to S_right=∑ ▒ 〖x[i] (I=K+1..N) S
S_left the maximum number of sub-sequences and the S_right The maximum number of subsequence and the and is the maximum of the Gemini sequence and
The problem to be solved now is to introduce a pair of new quantities, lf[i] and Lr[i], representing the largest sequence in the subsequence from leftmost, right to I, respectively.
On the basis of knowing Lmax (and Rmax), we can easily get LF and LR, just scan it again.
For space-saving considerations, we continue to use Lmax and rmax to denote LF and LR
Code
1lmax[0] = x[0];
2
3 for(intI=1; i<n; i++)
4
5if(lmax[i-1]<=0)
6
7Lmax[i]=x[i];
8
9Else
Ten
Onelmax[i]=lmax[i-1] + x[i];
A
-/*this section ibid .*/
-
the for(intI=1; i<n; i++)
-
-if(lmax[i]<lmax[i-1])
-
+lmax[i]=lmax[i-1];
-
+/*right side .*/
A
atrmax[n-1]=rmax[n-2];
-
- for(inti=n-1; i>=0; i--)
-
-if(rmax[i+1]<=0)
-
inRmax[i]=x[i];
-
toElse
+
-rmax[i]=rmax[i+1] + x[i];
the
* for(inti=n-1; i>=0; i--)
$
Panax Notoginsengif(rmax[i]<rmax[i+1])
-
thermax[i]=rmax[i+1];
+
AView Code
Add
For this problem, there is a relatively complex O (NLOGN) solution, which is to use recursion. This would be the best algorithm if we were to find out the position of the sequence (because we would have an O (N) algorithm later, but we couldn't find the position of the maximum subsequence). In this method we adopt the "divide and Conquer strategy" (Divide-and-conquer).
In our case, the maximal subsequence may appear in three places, either in the left half, or in the right half, or across the middle of the input data. The first two cases are solved recursively, and the third case is maximal and can be obtained by finding the largest sum of the first half and (including the last element of the first half) and the largest sum of the second half (including the first element of the second half).
Recursive method, Complexity is O (NLOGN)
Long Maxsumrec (const vector<int>& A, int left, int. right)
{
if (left = = right)
{
if (A[left] > 0)
return A[left];
Else
return 0;
}
int center = (left + right)/2;
Long maxleftsum = Maxsumrec (A, left, center);
Long maxrightsum = Maxsumrec (A, center+1, right);
Find the maximum value of the sequence ending with the last digit on the left
Long maxleftbordersum = 0, leftbordersum = 0;
for (int i = center, I >= left; i--)
{
Leftbordersum + = A[i];
if (Leftbordersum > Maxleftbordersum)
Maxleftbordersum = Leftbordersum;
}
Find the maximum value of the sequence ending with the next number on the right
Long maxrightbordersum = 0, rightbordersum = 0;
for (int j = center+1, J <= Right; J + +)
{
Rightbordersum + = A[j];
if (Rightbordersum > Maxrightbordersum)
Maxrightbordersum = Rightbordersum;
}
Return Max3 (Maxleftsum, Maxrightsum,
Maxleftbordersum + maxrightbordersum);
}
Long maxSubSum3 (const vector<int>& a)
{
Return Maxsumrec (A, 0, a.size ()-1);
}
In addition Max3 (Long,long,long) indicates the maximum value of three long:
Find the maximum value in three long
Long Max3 (long A, long B, long C)
{
if (a < b)
{
A = b;
}
if (a > C)
return A;
Else
return C;
}
The algorithm is analyzed:
T (1) = 1
T (n) = 2T (N/2) + O (n)
Finally, the complexity of the algorithm is: O (NLOGN).
Supplemental part from
Sub-sequence is the most large