user1057741
user1057741

Reputation: 265

Find max sum of elements in an array ( with twist)

Given a array with +ve and -ve integer , find the maximum sum such that you are not allowed to skip 2 contiguous elements ( i.e you have to select at least one of them to move forward).

eg :-

10 , 20 , 30, -10 , -50 , 40 , -50, -1, -3

Output : 10+20+30-10+40-1 = 89

Upvotes: 7

Views: 17592

Answers (12)

Rishabh Gupta
Rishabh Gupta

Reputation: 1

This question can be solved using include,exclude approach.

For first element, include = arr[0], exclude = 0.

For rest of the elements:

nextInclude = arr[i]+max(include, exclude)

nextExclude = include 

include = nextInclude

exclude = nextExclude

Finally, ans = Math.max(include,exclude).

Similar questions can be referred at (Not the same)=> https://www.youtube.com/watch?v=VT4bZV24QNo&t=675s&ab_channel=Pepcoding.

Upvotes: 0

CheshireCatNick
CheshireCatNick

Reputation: 1

The correct recurrence is as follow:

dp[i] = max(dp[i - 1] + a[i], dp[i - 2] + a[i - 1])

The first case is the one we pick the i-th element. The second case is the one we skip the i-th element. In the second case, we must pick the (i-1)th element.

The problem of IVlad's answer is that it always pick i-th element, which can lead to incorrect answer.

Upvotes: 0

Shubham Gupta
Shubham Gupta

Reputation: 11

Simple Solution: Skip with twist :). Just skip the smallest number in i & i+1 if consecutive -ve. Have if conditions to check that till n-2 elements and check for the last element in the end.

int getMaxSum(int[] a) {
    int sum = 0;
    for (int i = 0; i <= a.length-2; i++) {
        if (a[i]>0){
            sum +=a[i];
            continue;
        } else if (a[i+1] > 0){
            i++;
            continue;
        } else {
            sum += Math.max(a[i],a[i+1]);
            i++;
        }
    }
    if (a[a.length-1] > 0){
        sum+=a[a.length-1];
    }
    return sum;
}

Upvotes: 0

Anshul Garg
Anshul Garg

Reputation: 313

If you want to avoid using Dynamic Programming

  • To find the maximum sum, first, you've to add all the positive numbers.
  • We'll be skipping only negative elements. Since we're not allowed to skip 2 contiguous elements, we will put all contiguous negative elements in a temp array, and can figure out the maximum sum of alternate elements using sum_odd_even function as defined below.

  • Then we can add the maximum of all such temp arrays to our sum of all positive numbers. And the final sum will give us the desired output.

Code:

def sum_odd_even(arr):
    sum1 = sum2 = 0
    for i in range(len(arr)):
        if i%2 == 0:
            sum1 += arr[i]
        else:
            sum2 += arr[i]
    return max(sum1,sum2)

input = [10, 20, 30, -10, -50, 40, -50, -1, -3]
result = 0
temp = []
for i in range(len(input)):
    if input[i] > 0:
        result += input[i]
    if input[i] < 0 and i != len(input)-1:
        temp.append(input[i])
    elif input[i] < 0:
        temp.append(input[i])
        result += sum_odd_even(temp)
        temp = []
    else:
        result += sum_odd_even(temp)
        temp = []

print result

Upvotes: 0

Abhishek
Abhishek

Reputation: 551

n = arr.length(). Append a 0 at the end of the array to handle boundary case. ans: int array of size n+1. ans[i] will store the answer for array a[0...i] which includes a[i] in the answer sum. Now,

ans[0] = a[0]
ans[1] = max(a[1], a[1] + ans[0])
for i in [2,n-1]: 
   ans[i] = max(ans[i-1] , ans[i-2]) + a[i]

Final answer would be a[n]

Upvotes: 0

bhavneet
bhavneet

Reputation: 61

Let the array be of size N, indexed as 1...N

Let f(n) be the function, that provides the answer for max sum of sub array (1...n), such that no two left over elements are consecutive.

 f(n) = max (a[n-1] + f(n-2), a(n) + f(n-1))

In first option, which is - {a[n-1] + f(n-2)}, we are leaving the last element, and due to condition given in question selecting the second last element.

In the second option, which is - {a(n) + f(n-1)} we are selecting the last element of the subarray, so we have an option to select/deselect the second last element.

Now starting from the base case :

f(0) = 0   [Subarray (1..0) doesn't exist]

f(1) = (a[1] > 0 ? a[1] : 0);    [Subarray (1..1)]

f(2) = max( a(2) + 0, a[1] + f(1))   [Choosing atleast one of them]

Moving forward we can calculate any f(n), where n = 1...N, and store them to calculate next results. And yes, obviously, the case f(N) will give us the answer.

Time complexity o(n)
Space complexity o(n)

Upvotes: 0

vantony
vantony

Reputation: 513

This problem can be solved using Dynamic Programming approach.

Let arr be the given array and opt be the array to store the optimal solutions. opt[i] is the maximum sum that can be obtained starting from element i, inclusive.

opt[i] = arr[i] + (some other elements after i)

Now to solve the problem we iterate the array arr backwards, each time storing the answer opt[i]. Since we cannot skip 2 contiguous elements, either element i+1 or element i+2 has to be included in opt[i].

So for each i, opt[i] = arr[i] + max(opt[i+1], opt[i+2])

See this code to understand:

int arr[n];  // array of given numbers. array size = n.
nput(arr, n);   // input the array elements (given numbers)

int opt[n+2];   // optimal solutions. 
memset(opt, 0, sizeof(opt));    // Initially set all optimal solutions to 0.

for(int i = n-1; i >= 0; i--) {
    opt[i] = arr[i] + max(opt[i+1], opt[i+2]);
}

ans = max(opt[0], opt[1])   // final answer.

Observe that opt array has n+2 elements. This is to avoid getting illegal memory access exception (memory out of bounds) when we try to access opt[i+1] and opt[i+2] for the last element (n-1).

See the working implementation of the algorithm given above

Upvotes: 8

Viraj Talaty
Viraj Talaty

Reputation: 15

public static void countSum(int[] a) {
        int count = 0;
        int skip = 0;
        int newCount = 0;

        if(a.length==1)
        {
            count = a[0];
        }
        else
        {
            for(int i:a)
            {
                newCount = count + i;
                if(newCount>=skip)
                {
                    count = newCount;
                    skip = newCount;
                }
                else
                {
                    count = skip;
                    skip = newCount;
                }
            }
        }
        System.out.println(count);
    }
}

Upvotes: 0

sai sandeep
sai sandeep

Reputation: 1

I think this answer will help to you.

Given array:

Given:- 10 20 30 -10 -50 40 -50 -1 -3

Array1:-10 30 60  50  10 90  40 89 86

Array2:-10  20 50  40  0  80  30 79 76

Take the max value of array1[n-1],array1[n],array2[n-1],array2[n] i.e 89(array1[n-1])

Algorithm:-

  1. For the array1 value assign array1[0]=a[0],array1=a[0]+a[1] and array2[0]=a[0],array2[1]=a[1].
  2. calculate the array1 value from 2 to n is max of sum of array1[i-1]+a[i] or array1[i-2]+a[i].

    for loop from 2 to n{    
        array1[i]=max(array1[i-1]+a[i],array1[i-2]+a[i]);
    
    }
    
  3. similarly for array2 value from 2 to n is max of sum of array2[i-1]+a[i] or array2[i-2]+a[i].

    for loop from 2 to n{    
     array2[i]=max(array2[i-1]+a[i],array2[i-2]+a[i]);    
    }
    
  4. Finally find the max value of array1[n-1],array[n],array2[n-1],array2[n];

       int max(int a,int b){      
       return a>b?a:b;    
       }
    
       int main(){    
       int a[]={10,20,30,-10,-50,40,-50,-1,-3};    
       int i,n,max_sum;    
       n=sizeof(a)/sizeof(a[0]);    
       int array1[n],array2[n];    
       array1[0]=a[0];    
       array1[1]=a[0]+a[1];    
       array2[0]=a[0];    
        array2[1]=a[1];    
    
        for loop from 2 to n{    
        array1[i]=max(array1[i-1]+a[i],array1[i-2]+a[i]);    
        array2[i]=max(array2[i-1]+a[i],array2[i-2]+a[i]);
    
        }    
           --i;
    
        max_sum=max(array1[i],array1[i-1]);    
        max_sum=max(max_sum,array2[i-1]);    
        max_sum=max(max_sum,array2[i]);    
    
         printf("The max_sum is %d",max_sum);    
          return 0;    
        } 
    

Ans: The max_sum is 89

Upvotes: 0

Sandeep
Sandeep

Reputation: 7334

If you see a +ve integer add it to the sum. If you see a negative integer, then inspect the next integer pick which ever is maximum and add it to the sum.

10 , 20 , 30, -10 , -50 , 40 , -50, -1, -3

For this add 10, 20, 30, max(-10, -50), 40 max(-50, -1) and since there is no element next to -3 discard it.

The last element will go to sum if it was +ve.

Upvotes: 2

rohankvashisht
rohankvashisht

Reputation: 563

Answer:


I think this algorithm will help.

1. Create a method which gives output the maximum sum of particular user input array say T[n], where n denotes the total no. of elements.
2. Now this method will keep on adding array elements till they are positive. As we want to maximize the sum and there is no point in dropping positive elements behind.
3. As soon as our method encounters a negative element, it will transfer all consecutive negative elements to another method which create a new array say N[i] such that this array will contain all the consecutive negative elements that we encountered in T[n] and returns N[i]'s max output.
In this way our main method is not affected and its keep on adding positive elements and whenever it encounters negative element, it instead of adding their real values adds the net max output of that consecutive array of negative elements.

for example: T[n] = 29,34,55,-6,-5,-4,6,43,-8,-9,-4,-3,2,78 //here n=14

Main Method Working:

29+34+55+(sends data & gets value from Secondary method of array [-6,-5,-4])+6+43+(sends data & gets value from Secondary method of array [-8,-9,-4,-3])+2+78
Process Terminates with max output.

Secondary Method Working:
{

N[i] = gets array from Main method or itself as and when required. This is basically a recursive method.
say N[i] has elements like N1, N2, N3, N4, etc.

for i>=3:
Now choice goes like this.
1. If we take N1 then we can recurse the left off array i.e. N[i-1] which has all elements except N1 in same order. Such that the net max output will be
N1+(sends data & gets value from Secondary method of array N[i-1] recursively)
2. If we doesn't take N1, then we cannot skip N2. So, Now algorithm is like 1st choice but starting with N2. So max output in this case will be
N2+(sends data & gets value from Secondary method of array N[i-2] recursively). Here N[i-2] is an array containing all N[i] elements except N1 & N2 in same order.
Termination: When we are left with the array of size one ( for N[i-2] ) then we have to choose that particular value as no option.
The recursions will finally yield the max outputs and we have to finally choose the output of that choice which is more. and redirect the max output to wherever required.

for i=2:
we have to choose the value which is bigger

for i=1:
We can surely skip that value.
So max output in this case will be 0.

}

Upvotes: 0

IVlad
IVlad

Reputation: 43477

Use a recurrence that accounts for that:

dp[i] = max(dp[i - 1] + a[i], <- take two consecutives
            dp[i - 2] + a[i], <- skip a[i - 1])

Base cases left as an exercise.

Upvotes: 7

Related Questions