Problem:
Score : 600 points

Problem Statement

Given is an integer sequence A_1, ..., A_N of length N.

We will choose exactly \left\lfloor \frac{N}{2} \right\rfloor elements from this sequence so that no two adjacent elements are chosen.

Find the maximum possible sum of the chosen elements.

Here \lfloor x \rfloor denotes the greatest integer not greater than x.

Constraints

2 \leq N \leq 2\times 10^5

|A_i|\leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 ... A_N

Output

Print the maximum possible sum of the chosen elements.

Sample Input 1

6
1 2 3 4 5 6

Sample Output 1

12

Choosing 2, 4, and 6 makes the sum 12, which is the maximum possible value.

Sample Input 2

5
-1000 -100 -10 0 10

Sample Output 2

0

Choosing -10 and 10 makes the sum 0, which is the maximum possible value.

Sample Input 3

10
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000

Sample Output 3

5000000000

Watch out for overflow.

Sample Input 4

27
18 -28 18 28 -45 90 -45 23 -53 60 28 -74 -71 35 -26 -62 49 -77 57 24 -70 -93 69 -99 59 57 -49

Sample Output 4

295

Solution in Java (OpenJDK 11.0.6) (judge verdict: Accepted)

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.HashMap;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Spandan Mishra
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        FSelectHalf solver = new FSelectHalf();
        solver.solve(1, in, out);
        out.close();
    }

    static class FSelectHalf {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.readInt();
            int[] a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = in.readInt();

            System.out.println(selectHalf(a, n));

        }

        long selectHalf(int[] a, int n) {
//        long[][] dp = new long[n / 2 + 1][n + 1]; // cnt x n
//        for (int i = 0; i < dp.length; i++)
//            for (int j = 0; j < dp[i].length; j++)
//                dp[i][j] = Long.MIN_VALUE;

            HashMap<String, Long> dp = new HashMap<>();

            long ans = shUtils(0, 0, a, n, dp); // cnt and index passed
            return ans;
        }

        long shUtils(int cnt, int curr, int[] a, int n, HashMap<String, Long> dp) {
            if (cnt >= n / 2) {
                return 0;
            }

            if (curr >= n) {
                return Long.MIN_VALUE;
            }

            // curr query conditon modify to avoid unncessary query

            int size = n - curr;
            int max = (size + 1) / 2;
            int req = n / 2 - cnt;

            if (req > max)
                return Long.MIN_VALUE;


//        Pair p = new Pair();
//        p.cnt = cnt;
//        p.curr = curr;

            String s = cnt + " " + curr;


//        Long tempVal = dp.get(p);
            Long tempVal = dp.get(s);

            if (tempVal != null) {
//            System.out.println("tempVal = " + tempVal);
                return tempVal;
            }

            long tmp = shUtils(cnt + 1, curr + 2, a, n, dp);
            long choice1;
            if (tmp == Long.MIN_VALUE)
                choice1 = tmp;
            else
                choice1 = a[curr] + tmp;

            long choice2 = shUtils(cnt, curr + 1, a, n, dp);

//        dp[cnt][curr] = Math.max(choice1, choice2);
//        return dp[cnt][curr];

            long ans = Math.max(choice1, choice2);
            dp.put(s, ans);

            return ans;

//        return Math.max(choice1, choice2);


        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1)
                throw new RuntimeException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new RuntimeException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

    }
}