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 Rust (1.42.0) (judge verdict: Accepted)

use std::io::Read;

fn nmax(a: Option<i64>, b: Option<i64>) -> Option<i64> {
    if a.is_none() {
        return b;
    }
    if b.is_none() {
        return a;
    }
    Some(std::cmp::max(a.unwrap(), b.unwrap()))
}
fn main() {
    let mut line = String::new();
    std::io::stdin().read_to_string(&mut line);
    let mut it = line.split_whitespace();
    it.next().unwrap();
    let mut a = it.map(|a|a.parse().unwrap()).collect::<Vec<i64>>();
    let mut n = a.len();
    let mut k = n as i64 / 2;
    // i番目を選択前にk個選んでいるとした時に最大と最小のk
    let mut min_count = vec![0usize; n + 1];
    let mut max_count = vec![0usize; n + 1];
    for i in 0..(n + 1) {
        max_count[i] = std::cmp::min(k as usize, (i + 1) / 2);
    }
    min_count[n] = k as usize;
    let mut flip = true;
    for i in (0..n).rev() {
        min_count[i] = min_count[i + 1] - if flip && min_count[i + 1] > 0{
            1
        } else {
            0
        };
        flip = !flip;
    }
    let max_diff = (&min_count).iter().zip((&max_count).iter()).map(|(mi, ma)| ma-mi).max().unwrap() as usize;
    let mut dp = vec![vec![vec![None; 2]; max_diff + 1];n + 1];
    dp[0][0][0] = Some(0);
    for i in 0..n {
        for j in 0..=max_diff {
            let cur = min_count[i] + j;
            if cur > max_count[i] {
                break;
            }
            // その数を足す
            if let Some(cur_max) = dp[i][j][0] {
                dp[i + 1][cur + 1 - min_count[i + 1]][1] = nmax(dp[i + 1][cur + 1 - min_count[i + 1]][1], Some(cur_max + a[i]));
            }
            // 足さない
            if cur >= min_count[i + 1] {
                dp[i + 1][cur - min_count[i + 1]][0] = nmax(dp[i + 1][cur - min_count[i + 1]][0], dp[i][j][0]);
                dp[i + 1][cur - min_count[i + 1]][0] = nmax(dp[i + 1][cur - min_count[i + 1]][0], dp[i][j][1]);
            }
        }
    }
    let mut ret =  None;
    for j in 0..=max_diff {
        for k in 0.. 2 {
            ret = nmax(ret, dp[n][j][k]);
        }
    }
    println!("{}", ret.unwrap());
}