Preface this is the question that I encountered during the September round of the 9du OJ competition last night. It is very interesting. I checked it this morning and I have already mentioned similar questions in "the beauty of programming, it seems that after I read "offoffoffer", the next book will be "The beauty of programming". I got up at today and wanted to see English. Unfortunately, I still got an algorithm question.
Description: given an array arr consisting of n integer elements, the array has positive and negative numbers. This array is not a general array, and its first and last are connected. One or more continuous elements in the array can form a sub-array, where such a sub-array arr [I],… Arr [n-1], arr [0],…, Arr [J]. Please use the most efficient method of acm_lover to find the maximum values of all consecutive sub-arrays (if all the elements in the array are negative, the maximum value is 0, ). Input: the input contains multiple test cases. Each test case has two rows. The first row is an integer N (1 = <n <= 100000), indicating the length of the array, in the second row, enter n integers (the absolute value of an integer is not greater than 1000 ). Output: For each test case, output the sub-array and the maximum value. Sample input: 61-2 3 5-1 256-1 5 4-7 sample output: 1014
Here we useArr [6] = {1,-2, 3, 5,-1, 2}For example, we will introduce the maximum number of subarrays not connected at the beginning and end, and this is a typical dynamic planning question. If sum [I] is the maximum subarray and of the first I data, the state transition equation is obtained: with the state transition equation, the code can be easily implemented (in C)
/*** The beginning and end are not connected */INT maxsumnoconnect (int * arr, int N) {int I, Max, * sum; sum = (int *) malloc (sizeof (INT) * n); sum [0] = max = arr [0]; for (I = 1; I <n; I ++) {If (sum [I-1]> 0) sum [I] = arr [I] + sum [I-1]; elsesum [I] = arr [I]; if (sum [I]> MAX) max = sum [I];} Free (SUM); return Max ;}
We can see that here we use the auxiliary array sum of O (N), you can consider directly simplifying the auxiliary space, the Code is as follows:
int maxSumNoConnectOne(int *arr, int n){int i, max, sum;max = sum = arr[0] > 0 ? arr[0] : 0;for (i = 1; i < n; i ++) {if ((arr[i] + sum) > 0) {sum += arr[i];max = max > sum ? max : sum;} else {sum = 0;max = max > arr[i] ? max : arr[i];}}return max;}
The largest array connected at the beginning and end and the Child array adjacent to the beginning and end of the array can be discussed in two cases: (1) if the largest array and the Child array do not cross the first element, then we can use the solution of the original problem to solve the problem. (2) If the largest and sub-arrays cross the first element, we can continue to discuss the problem in two cases: 1. if all array elements are positive, the sum of all elements is the maximum value of 2. if there is a negative number in the array, the largest and sub-arrays must not include some elements, and the elements not included must have the smallest and sub-arrays, in this way, we can first find the last vertex of the minimum and sub-array, and use the (1) method to traverse the array cyclically starting from the next vertex, we can get the largest and sub-arrays as shown in the figure below: (PS: I am relying on the picture. If you forget it, you can understand it.) (1) you can use the above-mentioned first-and-last-not-connected Method to Solve (2) The following steps are the typical Dynamic Planning Idea of the minimum and subarray cutoff coordinates, assuming sum [I] is the smallest sub-array and of the first I data, the state transition equation is: implementation code (C language)
/*** Minimum subarray and cutoff coordinate */INT indexinarrminsum (int * arr, int N) {int I, Loc, Min, * sum; sum = (int *) malloc (sizeof (INT) * n); min = sum [0] = arr [0]; loc = 0; for (I = 1; I <n; I ++) {If (sum [I-1]> 0) {sum [I] = arr [I];} else {sum [I] = arr [I] + sum [I-1];} If (sum [I] <min) {loc = I; min = sum [I] ;}} free (SUM); return LOC ;}
Loop traversal, as long as the minimum and subarray cutoff coordinates start at the next position.
/*** Start-end connection */INT maxsumconnect (int * arr, int N) {int index, I, Loc, cur, Max, * sum; sum = (int *) malloc (sizeof (INT) * n); Index = indexinarrminsum (ARR, n); max = sum [(index + 1) % N] = arr [(index + 1) % N]; for (I = 2; I <n; I ++) {// do not consider the ending coordinate of the minimum sub-array. The Loc = (index + I-1) % N; cur = (index + I) % N; If (sum [loc]> 0) {sum [cur] = arr [cur] + sum [loc];} else {sum [cur] = arr [cur];} If (sum [cur]> MAX) max = sum [cur];} Free (SUM); return Max ;}
AC code
# Include <stdio. h> # include <stdlib. h>/*** The beginning and end are not connected */INT maxsumnoconnect (int * arr, int N) {int I, Max, * sum; sum = (int *) malloc (sizeof (INT) * n); sum [0] = max = arr [0]; for (I = 1; I <n; I ++) {If (sum [I-1]> 0) sum [I] = arr [I] + sum [I-1]; else sum [I] = arr [I]; if (sum [I]> MAX) max = sum [I];} Free (SUM); return Max ;} /*** minimum subarray and cutoff coordinate */INT indexinarrminsum (int * arr, int N) {int I, Loc, Min, * Sum; sum = (int *) malloc (sizeof (INT) * n); min = sum [0] = arr [0]; loc = 0; for (I = 1; I <n; I ++) {If (sum [I-1]> 0) {sum [I] = arr [I];} else {sum [I] = arr [I] + sum [I-1];} If (sum [I] <min) {loc = I; min = sum [I] ;}} free (SUM); return LOC;}/*** first and last connections */INT maxsumconnect (int * arr, int N) {int index, i, Loc, cur, Max, * sum; sum = (int *) malloc (sizeof (INT) * n); Index = indexinarrminsu M (ARR, n); max = sum [(index + 1) % N] = arr [(index + 1) % N]; for (I = 2; I <n; I ++) {// the cutoff coordinates of the minimum sub-array are not considered. The Loc = (index + I-1) % N; cur = (index + I) % N; If (sum [loc]> 0) {sum [cur] = arr [cur] + sum [loc];} else {sum [cur] = arr [cur];} If (sum [cur]> MAX) max = sum [cur];} Free (SUM); return Max ;} int main (void) {int I, n, flag, conn_n, conn_y, * arr; while (scanf ("% d", & N )! = EOF) {arr = (int *) malloc (sizeof (INT) * n); for (I = 0, flag = 0; I <n; I ++) {scanf ("% d", arr + I); If (* (ARR + I) <= 0) Flag ++ ;} // return 0 if (flag = N) {printf ("0 \ n"); continue;} conn_n = maxsumnoconnect (ARR, N ); conn_y = maxsumconnect (ARR, n); If (conn_n <conn_y) printf ("% d \ n", conn_y); else printf ("% d \ n", conn_n ); free (ARR);} return 0 ;} /*************************************** * *********************** problem: 1527 User: wangzhengyi language: C result: accepted time: 80 MS memory: 2084 kb ************************************** **************************/