Problem:
ケーキの切り分け２ (Cake 2)
JOI くんと IOI ちゃんは双子の兄妹である．JOI くんは最近お菓子作りに凝っていて，今日も JOI くんはケーキを焼いて食べようとしたのだが，焼きあがったところで匂いをかぎつけた IOI ちゃんが来たので 2人でケーキを分けることになった．
ケーキは円形である．ある点から放射状に切り目を入れ，ケーキを
N
個のピースに切り分け，ピースに 1 から
N
まで反時計回りに番号をつけた．つまり，1 ≤
i
≤
N
に対し，
i
番目のピースは
i
− 1 番目と
i
+ 1 番目のピースと隣接している (ただし 0 番目は
N
番目，
N
+ 1 番目は 1 番目とみなす) ．
i
番目のピースの大きさは
A
i
だったが，切り方がとても下手だったので
A
i
はすべて異なる値になった．
図 1: ケーキの例 (
N
= 5,
A
1
= 2,
A
2
= 8,
A
3
= 1,
A
4
= 10,
A
5
= 9)
この
N
個を JOI くんと IOI ちゃんで分けることにした．分け方は次のようにすることにした：
まず JOI くんが
N
個のうちの好きな 1 つを選んで取る．
その後，IOI ちゃんからはじめて IOI ちゃんと JOI くんが交互に残りのピースを 1 つずつ取っていく．ただし，両隣のピースのうち少なくとも一方が既に取られているようなピースしか取ることができず，取れるピースが複数あるときは，IOI ちゃんはそのうち最も大きいものを選んで取り，JOI くんはそのうちで好きなものを選んで取ることができる．
JOI くんは，自分が最終的に取るピースの大きさの合計を最大化したい．
課題
ケーキのピースの数
N
と，
N
個のピースの大きさの情報が与えられたとき，JOI くんが取れるピースの大きさの合計の最大値を求めるプログラムを作成せよ．
入力
標準入力から以下の入力を読み込め．
1 行目には整数
N
が書かれており，ケーキが
N
個のピースに切り分けられていることを表す．
続く
N
行のうちの
i
行目 (1 ≤
i
≤
N
) には整数
A
i
が書かれており，
i
番目のピースの大きさが
A
i
であることを表す．
出力
標準出力に，JOI くんが取れるピースの大きさの合計の最大値を表す整数を 1 行で出力せよ.
制限
すべての入力データは以下の条件を満たす．
1 ≤
N
≤ 2 000．
1 ≤
A
i
≤ 1 000 000 000．
A
i
はすべて異なる．
入出力例
入力例 1
5
2
8
1
10
9
出力例 1
18
JOI くんは，次のようにピースを取るのが最適である．
JOI くんは 2 番目のピースを取る．このピースの大きさは 8 である．
IOI ちゃんは 1 番目のピースを取る．このピースの大きさは 2 である．
JOI くんは 5 番目のピースを取る．このピースの大きさは 9 である．
IOI ちゃんは 4 番目のピースを取る．このピースの大きさは 10 である．
JOI くんは 3 番目のピースを取る．このピースの大きさは 1 である．
最終的に，JOI くんが取ったピースの大きさの合計は，8 + 9 + 1 = 18 となる.
入力例 2
8
1
10
4
5
6
2
9
3
出力例 2
26
入力例 3
15
182243672
10074562
977552215
122668426
685444213
3784162
463324752
560071245
134465220
21447865
654556327
183481051
20041805
405079805
564327789
出力例 3
3600242976
問題文と自動審判に使われるデータは、
情報オリンピック日本委員会
が作成し公開している問題文と採点用テストデータです。

Submitted solutions:

code_snippet: // #pragma GCC optimize("Ofast")
// #pragma GCC optimize ("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include<bits/stdc++.h>
using namespace std;

#include<complex>
//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>

#define x() real()
#define y() imag()
#define endl '\n'
#define ll long long
typedef long double T;
typedef complex<T> point;
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
#define fastIO cin.tie(0)->sync_with_stdio(0);

//using namespace __gnu_pbds;
//template <typename T> using o_set = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;

//If you can't solve a problem then there's an easier
//sub-problem that you can not solve.Find it!!

const int N = 4e3 + 5;
ll a[N] , dp[N][N][2];

int main()
{
    fastIO;

    int t = 1; //cin >> t;

    while (t--)
    {
        int n; cin >> n;

        for (int i = 1 ; i <= n ; i++)
        {
            cin >> a[i];
            a[i + n] = a[i];
        }

        for (int len = 1 ; len <= n + n ; len++)
        {
            for (int i = 1  , j = i + len - 1 ; j <= n + n; i++ , j++)
            {
                dp[i][j][0] = max(a[i] + dp[i + 1][j][1] ,
                                   dp[i][j - 1][1] + a[j]);

                if (a[i] > a[j])
                    dp[i][j][1] = dp[i + 1][j][0];

                else
                    dp[i][j][1] = dp[i][j - 1][0];
            }
        }

        ll ans = 0;

        for (int i = 1 ; i <= n ; i++)
            ans = max(ans , a[i] + dp[i + 1][i + n - 1][1]);

         cout << ans << endl;

         //cout << dp[1][2][1] << endl;
    }



    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 253304
final_rank: 18

code_snippet: #include<iostream>
#include<algorithm>
using namespace std;
long long n, a[10000], dp[3000][3000];
int main() {
	cin >> n; for (int i = 0; i < n; i++)cin >> a[i];
	for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++)dp[i][j] = -99999999999999999LL; }
	for (int i = 0; i < n; i++)dp[i][i] = a[i];
	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < n; j++) {
			int L1 = j, R1 = (i + j) % n;
			int N1 = (L1 + n - 1) % n;
			int N2 = (R1 + 1) % n;
			if (i % 2 == 0) {
				if (a[N1] <= a[N2])dp[L1][N2] = max(dp[L1][N2], dp[L1][R1]);
				if (a[N1] > a[N2])dp[N1][R1] = max(dp[N1][R1], dp[L1][R1]);
			}
			if (i % 2 == 1) {
				dp[L1][N2] = max(dp[L1][N2], dp[L1][R1] + a[N2]);
				dp[N1][R1] = max(dp[N1][R1], dp[L1][R1] + a[N1]);
			}
		}
	}
	long long maxn = 0; for (int i = 0; i < n; i++)maxn = max(maxn, dp[(i + 1) % n][i]);
	cout << maxn << endl;
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 50148
final_rank: 9

code_snippet: // competitive-verifier: PROBLEM
#pragma GCC optimize("Ofast,fast-math,unroll-all-loops")
#include <bits/stdc++.h>
#if !defined(ATCODER) && !defined(EVAL)
#pragma GCC target("sse4.2,avx2,bmi2")
#endif
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = 3.14159265358979323846;
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m) - 1; i >= int(n); --i)
#define FORL(i, m, n) for (std::int64_t i = (m); i < std::int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }
    constexpr void operator()() const {}
} sonic;
struct increment_impl {
    template <class T>
    const increment_impl &operator>>(std::vector<T> &v) const {
        for (auto &x : v) ++x;
        return *this;
    }
} Inc;
struct decrement_impl {
    template <class T>
    const decrement_impl &operator>>(std::vector<T> &v) const {
        for (auto &x : v) --x;
        return *this;
    }
} Dec;
struct sort_impl {
    template <class T>
    const sort_impl &operator>>(std::vector<T> &v) const {
        std::sort(v.begin(), v.end());
        return *this;
    }
} Sort;
struct unique_impl {
    template <class T>
    const unique_impl &operator>>(std::vector<T> &v) const {
        std::sort(v.begin(), v.end());
        v.erase(std::unique(v.begin(), v.end()), v.end());
        return *this;
    }
} Uniq;
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) os << (it == v.begin() ? "" : " ") << *it;
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
void Yes(bool is_correct = true) { std::cout << (is_correct ? "Yes\n" : "No\n"); }
void No(bool is_not_correct = true) { Yes(!is_not_correct); }
void YES(bool is_correct = true) { std::cout << (is_correct ? "YES\n" : "NO\n"); }
void NO(bool is_not_correct = true) { YES(!is_not_correct); }
void Takahashi(bool is_correct = true) { std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n'; }
void Aoki(bool is_not_correct = true) { Takahashi(!is_not_correct); }
/// @brief 累積和
template <class T = std::int64_t>
struct prefix_sum {
    prefix_sum(int _n) : n(_n), data(_n + 1) {}
    template <class U>
    prefix_sum(const std::vector<U> &v) : n(v.size()), data(v.size() + 1) {
        for (int i = 0; i < n; ++i) data[i] = v[i];
        build();
    }
    void build() {
        for (int i = n - 1; i >= 0; --i) data[i] += data[i + 1];
    }
    T get(int k) const {
        assert(0 <= k && k < n);
        return data[k] - data[k + 1];
    }
    void set(int k, int x) { data[k] = x; }
    void add(int k, int x) { data[k] += x; }
    T sum(int r) const {
        assert(0 <= r && r <= n);
        return data[0] - data[r];
    }
    T sum(int l, int r) const {
        assert(0 <= l && l <= r && r <= n);
        return data[l] - data[r];
    }
    int min_left(T x) const { return min_left(0, x); }
    int min_left(int l, T x) const {
        assert(0 <= l && l <= n);
        int left = l, right = n + 1;
        while (right - left > 1) {
            int mid = (left + right) / 2;
            (data[l] - data[mid] >= x ? right : left) = mid;
        }
        return right;
    }
    int max_right(T x) const { return max_right(n, x); }
    int max_right(int r, T x) const {
        assert(0 <= r && r <= n);
        int left = -1, right = r;
        while (right - left > 1) {
            int mid = (left + right) / 2;
            (data[mid] - data[r] >= x ? left : right) = mid;
        }
        return left;
    }
  private:
    int n;
    std::vector<T> data;
};
int main(void) {
    int n;
    cin >> n;
    vector<int> a(n);
    cin >> a;
    rep (i, n) {
        a.emplace_back(a[i]);
    }
    vector dp(n * 2 + 1, vector(n * 2 + 1, 0l));
    repn (d, n * 2) {
        rep (l, n * 2) {
            int r = l + d;
            if (r > n * 2)
                break;
            if ((n - (r - l)) % 2 == 0)
                dp[l][r] = max(dp[l][r - 1] + a[r - 1], dp[l + 1][r] + a[l]);
            else {
                if (a[l] > a[r - 1])
                    dp[l][r] = dp[l + 1][r];
                else
                    dp[l][r] = dp[l][r - 1];
            }
        }
    }
    ll ans = 0;
    rep (i, n) chmax(ans, dp[i][i + n]);
    co(ans);
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 128640
final_rank: 14

code_snippet: #include <bits/stdc++.h>


using namespace std;
//make -f ../makefile SRC=
/*
jun pick first, ...
dp
e.g. for 5 cakes
kun:
0 1 2 3 4 => 0 1 X 3 4 = 5 6 X 3 4
next:
L=3, R=6, chan's turn

dp state: L, R, who's turn

N.B. only increment vect[i] when it's kun's turn (objective is to maximise kun's score)


FIXME:
retnink
L, R in circle,  L <= R ???????

*/


//------------------------------------------------------------------------------
bool DEBUG = false;
const int INF = 2147483647;

const int MAX_N = 2000;
static int vect[MAX_N];
static int64_t S[MAX_N][MAX_N]; // L, R

//------------------------------------------------------------------------------
void debug_S(int N)
{
    for (int i=0; i<N; ++i)
        for (int j=0; j<N; ++j)
            if (S[i][j] != -1)
                printf("i=%d, j=%d: %ld\n", i, j, S[i][j]);
}
int64_t dp(int N, int L, int R, bool chan)
{
    if (L < 0) L += N;
    if (L >= N) L %= N;
    if (R < 0) R += N;
    if (R >= N) R %= N;
    // N.B. do not swap if L > R

    if (S[L][R] != -1) return S[L][R];
    int64_t& res = S[L][R];
    res = 0;
    if (L == R)
    {
        if (!chan) res = vect[L];
        return res;
    }

    if (chan)
    {
        if (vect[L] > vect[R]) res = dp(N, L+1, R, false);
        else res = dp(N, L, R-1, false);
    }
    else
    {
        //if (vect[L] > vect[R]) res = vect[L] + dp(N, L+1, R, true);
        //else res = vect[R] + dp(N, L, R-1, true);
        res = max(vect[L] + dp(N, L+1, R, true), vect[R] + dp(N, L, R-1, true));
    }
    return res;
}
//------------------------------------------------------------------------------
int64_t solve(int N)
{
    //--------------------------------------------------------------------------
    // base cases:
    //--------------------------------------------------------------------------
    // init:
    for (int i=0; i<N; ++i) for (int j=0; j<N; ++j) S[i][j] = -1;
    //--------------------------------------------------------------------------
    // compute:
    int64_t res = 0;
    for (int i=0; i<N; ++i) res = max(res, dp(N, i+1, i-1, true) + vect[i]);
    if (DEBUG) debug_S(N);
    //--------------------------------------------------------------------------
    // report:
    return res;
}

//------------------------------------------------------------------------------
void test()
{

}

//------------------------------------------------------------------------------
int main()
{
    //test(); return 0;
    //DEBUG = true;
    //--------------------------------------------------------------------------
    int N, num;
    num = scanf("%d ", &N);
    for (int i=0; i<N; ++i) num = scanf("%d ", &vect[i]);
    int64_t res = solve(N);
    printf("%ld\n", res);
    //--------------------------------------------------------------------------
    return 0;
}
//------------------------------------------------------------------------------
accuracy: 1
time_ms: 30
memory_kb: 34876
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;


int main(){

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    ll N;
    cin>>N;
    vector<ll> A(N*2);
    for(int i=0;i<N;i++){
        cin>>A[i];
        A[i+N]=A[i];
    }
    vector<vector<ll>> DP(N*2,vector<ll>(N*2,0));
    if(N%2==1)for(int i=0;i<N*2;i++)DP[i][i]=A[i];
    for(int d=1;d<N;d++){
        for(int i=0;i<2*N;i++){
            int j=i+d;
            if(j>=2*N)break;
            if((N-d)%2==1){
                DP[i][j]=max(DP[i+1][j]+A[i],DP[i][j-1]+A[j]);
            }
            else{
                if(A[i]>A[j])DP[i][j]=DP[i+1][j];
                else DP[i][j]=DP[i][j-1];
            }
        }
    }
    ll an=0;
    for(int i=0;i<N;i++){
        an=max(an,A[i]+DP[i+1][i+N-1]);
    }
    cout<<an<<endl;
}
accuracy: 1
time_ms: 60
memory_kb: 128188
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <cstdio>
using namespace std;

int main() {
    vector<long long> a(2000, 0);  // 配列aを2000要素の初期化
    int n;
    vector<long long> dp(2000, 0);  // 配列dpを2000要素の初期化
    vector<long long> dq(2000, 0);  // 配列dqを2000要素の初期化
    long long ans;

    // 標準入力から配列サイズnを読み込み
    scanf("%d", &n);

    // 標準入力から配列aの要素を読み込み
    for (int i = 0; i < n; i++) {
        scanf("%lld", &a[i]);
    }

    // メインループ: 配列aの要素を使ってdp配列を更新
    for (int i = 0; i < n; i++) {
        if (i % 2 == 1) {
            for (int j = 0; j < n; j++) {
                int x = (i + j) % n;
                int y = (j + n - 1) % n;
                if (a[x] < a[y]) {
                    dq[y] = max(dq[y], dp[j]);
                } else {
                    dq[j] = max(dq[j], dp[j]);
                }
            }
        } else {
            for (int j = 0; j < n; j++) {
                int x = (i + j) % n;
                int y = (j + 1) % n;
                dq[j] = max(dp[j] + a[x], dp[y] + a[j]);
            }
        }

        // dqをdpにコピーしてdqをクリア
        for (int j = 0; j < n; j++) {
            dp[j] = dq[j];
            dq[j] = 0;
        }
    }

    // 最終結果を計算
    ans = 0;
    for (int i = 0; i < n; i++) {
        ans = max(ans, dp[i]);
    }

    // 結果を出力
    printf("%lld\n", ans);

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3620
final_rank: 1

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<ll> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    vector<vector<ll>> dp(n, vector<ll>(n, -1));
    if (n == 1) {
        cout << a[0] << endl;
        return 0;
    } else if (n == 2) {
        cout << max(a[0], a[1]) << endl;
        return 0;
    }
    auto calc = [&](auto self, int s, int m) -> ll {
        if (dp[s][m] != -1) return dp[s][m];
        if (m == 0) return 0;
        if (m == 1) return a[s];
        int l = s, r = (s + m - 1) % n;
        if (m == 2) {
            dp[s][m] = max(a[l], a[r]);
            return dp[s][m];
        }
        int l2 = (s + 1) % n, r2 = (r + n - 1) % n;
        int l3 = (l2 + 1) % n, r3 = (r2 + n - 1) % n;

        // lを使う場合
        {
            if (a[l2] > a[r]) dp[s][m] = max(dp[s][m], a[l] + self(self, l3, m - 2));
            else dp[s][m] = max(dp[s][m], a[l] + self(self, l2, m - 2));
        }
        // rを使う場合
        {
            if (a[l] > a[r2]) dp[s][m] = max(dp[s][m], a[r] + self(self, l2, m - 2));
            else dp[s][m] = max(dp[s][m], a[r] + self(self, l, m - 2));
        }

        return dp[s][m];
    };
    ll res = 0;
    for (int i = 0; i < n; ++i) {
        int p = (i == 0 ? n - 1 : i - 1);
        int c = (i + 1 == n ? 0 : i + 1);
        int cc = (i + 2 >= n ? i + 2 - n : i + 2);
        if (a[p] > a[c]) res = max(res, a[i] + calc(calc, c, n - 2));
        else res = max(res, a[i] + calc(calc, cc, n - 2));
    }
    cout << res << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 34512
final_rank: 5

code_snippet: /*
 * 0615.cc: Cake 2
 */

#include<cstdio>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_N = 2000;
const int MAX_N2 = MAX_N * 2;

/* typedef */

typedef long long ll;

/* global variables */

int as[MAX_N2];
ll dp[MAX_N2 + 1][MAX_N2 + 1];

/* subroutines */

/* main */

int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) scanf("%d", as + i), as[i + n] = as[i];

  int n2 = n * 2;
  for (int i = 0; i <= n2; i++) dp[i][i] = 0;
  for (int i = 0; i < n2; i++) dp[i][i + 1] = as[i];

  for (int l = 2; l <= n; l++)
    for (int i = 0, j = l; j <= n2; i++, j++)
      dp[i][j] =
	max(as[i] + (as[i + 1] > as[j - 1] ? dp[i + 2][j] : dp[i + 1][j - 1]),
	    as[j - 1] + (as[i] > as[j - 2] ? dp[i + 1][j - 1] : dp[i][j - 2]));

  ll maxd = 0;
  for (int i = 0; i < n; i++) maxd = max(maxd, dp[i][i + n]);

  printf("%lld\n", maxd);

  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 127164
final_rank: 10

code_snippet: #define rep(i,n) for(int i=0;i<(int)(n);i++)
#define ALL(v) v.begin(),v.end()
typedef long long ll;
 
#include<bits/stdc++.h>
using namespace std;

ll dp[4020][4020];
void chmax(ll &a,ll b){a=max(a,b);}
 
int main(){
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  
  int n;
  cin>>n;
  vector<ll> A(2*n);
  rep(i,n){
    cin>>A[i];
    A[i+n]=A[i];
  }
  
  if(n%2){
    rep(i,2*n) dp[i][i+1]=A[i];
    for(int w=2;w<=2*n;w++){
      for(int l=0;l+w<=2*n;l++){
        int r=l+w;
        if(w%2){
          chmax(dp[l][r],A[l]+dp[l+1][r]);
          chmax(dp[l][r],dp[l][r-1]+A[r-1]);
        }
        else{
          if(A[l]>A[r-1]) chmax(dp[l][r],dp[l+1][r]);
          else chmax(dp[l][r],dp[l][r-1]);
        }
      }
    }
  }
  else{
    for(int w=2;w<=2*n;w++){
      for(int l=0;l+w<=2*n;l++){
        int r=l+w;
        if(w%2==0){
          chmax(dp[l][r],A[l]+dp[l+1][r]);
          chmax(dp[l][r],dp[l][r-1]+A[r-1]);
        }
        else{
          if(A[l]>A[r-1]) chmax(dp[l][r],dp[l+1][r]);
          else chmax(dp[l][r],dp[l][r-1]);
        }
      }
    }
  }
  ll ans=0;
  rep(i,n) ans=max(ans,dp[i][i+n]);
  cout<<ans<<endl;
    
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 128408
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using i32 = int;
using i64 = long long;

i64 rec(vector<vector<i64>>& dp, vector<vector<bool>>& used, const vector<i32>& as, i32 l, i32 r) {
    if (used[l][r]) {
        return dp[l][r];
    }
    used[l][r] = true;
    i32 n = (i32)as.size();
    if (l != r and l % n == r % n) {
        return dp[l][r] = 0LL;
    }
    if ((r - l) & 1) {
        if (as[(l - 1 + n) % n] > as[r % n]) {
            if (l == 0) {
                return dp[l][r] = rec(dp, used, as, 2 * n - 1, r);
            }
            else {
                return dp[l][r] = rec(dp, used, as, l - 1, r);
            }
        }
        else {
            return dp[l][r] = rec(dp, used, as, l, r + 1);
        }
    }
    else {
        i64 f = 0;
        if (l == 0) {
            f = rec(dp, used, as, 2 * n - 1, r);
        }
        else {
            f = rec(dp, used, as, l - 1, r);
        }
        i64 b = rec(dp, used, as, l, r + 1);
        return dp[l][r] = max(f + as[(l - 1 + n) % n], b + as[r % n]);
    }
}

int main() {
    i32 n; cin >> n;
    vector as(n, 0);
    for (auto& a : as) cin >> a;
    vector dp(2 * n + 1, vector(2 * n + 1, 0LL));
    vector used(2 * n + 1, vector(2 * n + 1, false));
    i64 ans = 0;
    for (i32 i = 0 ; i < n ; i++) {
        ans = max(ans, rec(dp, used, as, i, i));
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 100
memory_kb: 130732
final_rank: 16

code_snippet: #include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll dp[2001][2000];
int main(){
	int n,a[2000];
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i];
	for(int w=0;w<n;w++){
		for(int i=0;i<n;i++){
			if(w%2==0){
				dp[w+1][i]=max(dp[w+1][i],dp[w][i]+a[(i+w)%n]);
				dp[w+1][(i+n-1)%n]=max(dp[w+1][(i+n-1)%n],dp[w][i]+a[(i+n-1)%n]);
			}else if(a[(i+w)%n]>a[(i+n-1)%n])
				dp[w+1][i]=max(dp[w+1][i],dp[w][i]);
			else
				dp[w+1][(i+n-1)%n]=max(dp[w+1][(i+n-1)%n],dp[w][i]);
		}
	}
	cout<<*max_element(dp[n],dp[n]+n)<<endl;
}
accuracy: 1
time_ms: 20
memory_kb: 34672
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define drep(i,j,n) for(int i=0;i<(int)(n-1);i++)for(int j=i+1;j<(int)(n);j++)
#define trep(i,j,k,n) for(int i=0;i<(int)(n-2);i++)for(int j=i+1;j<(int)(n-1);j++)for(int k=j+1;k<(int)(n);k++)
#define codefor int test;scanf("%d",&test);while(test--)
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define yes(ans) if(ans)printf("yes\n");else printf("no\n")
#define Yes(ans) if(ans)printf("Yes\n");else printf("No\n")
#define YES(ans) if(ans)printf("YES\n");else printf("NO\n")
#define popcount(v) __builtin_popcount(v)
#define vector2d(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define vector3d(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
#define umap unordered_map
#define uset unordered_set
using namespace std;
using ll = long long;
const int MOD=1000000007;
const int MOD2=998244353;
const int INF=1<<30;
const ll INF2=(ll)1<<60;
void scan(int& a){scanf("%d",&a);}
void scan(long long& a){scanf("%lld",&a);}
template<class T,class L>void scan(pair<T, L>& p){scan(p.first);scan(p.second);}
template<class T,class U,class V>void scan(tuple<T,U,V>& p){scan(get<0>(p));scan(get<1>(p));scan(get<2>(p));}
template<class T> void scan(T& a){cin>>a;}
template<class T> void scan(vector<T>& vec){for(auto&& it:vec)scan(it);}
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){scan(head);in(tail...);}
void print(const int& a){printf("%d",a);}
void print(const long long& a){printf("%lld",a);}
void print(const double& a){printf("%.15lf",a);}
template<class T,class L>void print(const pair<T, L>& p){print(p.first);putchar(' ');print(p.second);}
template<class T> void print(const T& a){cout<<a;}
template<class T> void print(const vector<T>& vec){if(vec.empty())return;print(vec[0]);for(auto it=vec.begin();++it!= vec.end();){putchar(' ');print(*it);}}
void out(){putchar('\n');}
template<class T> void out(const T& t){print(t);putchar('\n');}
template <class Head, class... Tail> void out(const Head& head,const Tail&... tail){print(head);putchar(' ');out(tail...);}
template<class T> void dprint(const T& a){cerr<<a;}
template<class T> void dprint(const vector<T>& vec){if(vec.empty())return;cerr<<vec[0];for(auto it=vec.begin();++it!= vec.end();){cerr<<" "<<*it;}}
void debug(){cerr<<endl;}
template<class T> void debug(const T& t){dprint(t);cerr<<endl;}
template <class Head, class... Tail> void debug(const Head& head, const Tail&... tail){dprint(head);cerr<<" ";debug(tail...);}
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
ll modinv(ll a, ll m) {ll b = m, u = 1, v = 0;while (b) {ll t = a / b;a -= t * b; swap(a, b);u -= t * v; swap(u, v);}u %= m;if (u < 0) u += m;return u;}
ll updivide(ll a,ll b){if(a%b==0) return a/b;else return (a/b)+1;}
template<class T> void chmax(T &a,const T b){if(b>a)a=b;}
template<class T> void chmin(T &a,const T b){if(b<a)a=b;}

int main(){
    INT(n);
    vector<ll> a(n);
    in(a);
    rep(i,n)a.push_back(a[i]);
    vector2d(ll,dp,2*n,2*n,-INF2);
    function<ll(int,int)> rec=[&](int l,int r){
        if(l>r)return 0LL;
        ll res=0;
        if(dp[l][r]!=-INF2)return dp[l][r];
        if((n-(r-l))&1){
            res=-INF2;
            chmax(res,a[l]+rec(l+1,r));
            chmax(res,a[r]+rec(l,r-1));
        }else{
            res=INF2;
            if(a[l]>=a[r])chmin(res,-a[l]+rec(l+1,r));
            if(a[l]<=a[r])chmin(res,-a[r]+rec(l,r-1));
        }
        return dp[l][r]=res;
    };
    ll ans=0,sumv=0;
    rep(i,n)sumv+=a[i];
    rep(i,n)chmax(ans,(sumv+rec(i,i+n-1))/2);
    out(ans);
}
accuracy: 1
time_ms: 80
memory_kb: 128540
final_rank: 15

code_snippet: #include <iostream>
#include <utility>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <map>
#include <set>
#include <queue>
using namespace std;
using ll = long long int;
#define chmax(x,y)  (x) = ((x) > (y)) ? (x) : ((x) = (y));
#define chmin(x,y)  (x) = ((x) < (y)) ? (x) : ((x) = (y));
const int INF = 1e9;
const ll INFL = 1e18;
const int Mod = 1e9 + 7;
const int dx[] = {0,1,0,-1};
const int dy[] = {1,0,-1,0};


int main(int argc, char const *argv[])
{
  int N;cin >> N;
  vector<ll> A(2*N);
  for(int i=0;i<N;++i)
  {
    cin >> A[i]; A[i+N] = A[i];
  }
  vector<vector<ll>> dp(2*N+1,vector<ll>(2*N+1));
  //if(N%2)for(int i=0;i<2*N;++i)dp[i][i+1] = A[i];
  for(int len = 1;len <=N;++len)
  {
    for(int i=0;i<2*N;++i)
    {
      if(i+len > 2*N)continue;
      if(N%2 == len%2)
      {
        dp[i][i+len] = max(dp[i+1][i+len]+A[i],dp[i][i+len-1]+A[i+len-1]);
      }
      else 
      {
        if(A[i] > A[i+len-1])dp[i][i+len] = dp[i+1][i+len];
        else dp[i][i+len] = dp[i][i+len-1];
      }
    }
  }
  ll answer = 0;
  for(int i=0;i<N;++i)
  {
    //std::cout << dp[i][i+N] << std::endl;
    chmax(answer,dp[i][i+N]);
  }
  std::cout << answer << std::endl;
}
accuracy: 1
time_ms: 60
memory_kb: 128236
final_rank: 13

code_snippet: bool TEST = false;

using namespace std;
#include<bits/stdc++.h>
#include<fstream>

#define rep(i,n) for(int (i)=0;(i)<(ll)(n);i++)
#define repr(i,n) for(int (i)=(ll)(n)-1;(i)>=0;i--)
#define range(i,start,end,step) for(int (i)=start;(i)<(ll)(end);(i)+=(step))

#define dump(x)  cerr << "Line " << __LINE__ << ": " <<  #x << " = " << (x) << "\n";
#define spa << " " <<
#define fi first
#define se second
#define all(a)  (a).begin(),(a).end()
#define allr(a)  (a).rbegin(),(a).rend()

using ld = long double;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<ld, ld>;
 
template<typename T> using V = vector<T>;
template<typename T> using VV = V<V<T>>;
template<typename T, typename T2> using P = pair<T, T2>;
template<typename T, typename T2> using M = map<T, T2>;
template<typename T> using S = set<T>;
template<typename T, typename T2> using UM = unordered_map<T, T2>;
template<typename T> using PQ = priority_queue<T, V<T>, greater<T>>;
template<typename T> using rPQ = priority_queue<T, V<T>, less<T>>;
template<typename T> vector<T> make_vec(size_t n, T a) { return vector<T>(n, a); }
template<typename... Ts> auto make_vec(size_t n, Ts... ts) { return vector<decltype(make_vec(ts...))>(n, make_vec(ts...)); }
template<class SS, class T> ostream& operator << (ostream& os, const pair<SS, T> v){os << "(" << v.first << ", " << v.second << ")"; return os;}
template<typename T> ostream& operator<<(ostream &os, const vector<T> &v) { for (auto &e : v) os << e << ' '; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<vector<T>> &v){ for(auto &e : v){os << e << "\n";} return os;}
struct fast_ios { fast_ios(){ cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
 
template <class T> void UNIQUE(vector<T> &x) {sort(ALL(x));x.erase(unique(ALL(x)), x.end());}
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
void fail() { cout << -1 << '\n'; exit(0); }
inline int popcount(const int x) { return __builtin_popcount(x); }
inline int popcount(const ll x) { return __builtin_popcountll(x); }
template<typename T> void debug(vector<vector<T>>&v){for(ll i=0;i<v.size();i++)
{cerr<<v[i][0];for(ll j=1;j<v[i].size();j++)cerr spa v[i][j];cerr<<"\n";}};
template<typename T> void debug(vector<T>&v){if(v.size()!=0)cerr<<v[0];
for(ll i=1;i<v.size();i++)cerr spa v[i];
cerr<<"\n";};
template<typename T> P<T,T> divmod(T a, T b) {return make_pair(a/b, a%b);}

const ll INF = (1ll<<62);
// const ld EPS   = 1e-10;
// const ld PI    = acos(-1.0);
const ll mod = (int)1e9 + 7;
//const ll mod = 998244353;


ll dp[2010][2010];
int n;
V<ll> a;

ll sub(int l, int r, bool f = 1) {
    l = (l+n)%n;
    r = (r+n)%n;
    ll res = 0;
    if (r==l && f) return 0;
    if (dp[l][r]>=0) return dp[l][r];
    else {
        int nl,nnl,nr,nnr;
        ll vl,vl2,vr,vr2;
        nl = (n+l-1)%n;
        nnl = (n+l-2)%n;
        nr = (r)%n;
        nnr = (r+1)%n;
        vl = a[nl];
        vl2 = a[nnl];
        vr = a[nr];
        vr2 = a[nnr];
        if ((r-l+2*n)%n==n-1) {
            assert(vl==vr);
            // cout << l spa r spa vl spa vr;
            res = vl;
        } else {
            if (vl2<vr) chmax(res, sub(l-1,r+1) + vl);
            else chmax(res, sub(l-2,r,1) + vl);
            if (vl<vr2) chmax(res, sub(l, r+2) + vr);
            else chmax(res, sub(l-1,r+1) + vr);
        }
    }
    // cout << l spa r spa res << endl;
    dp[l][r] = res;
    return res;
}
void Main(){
    cin >> n;
    a = V<ll>(n);
    rep(i,n) cin >> a[i];
    rep(i,n+10) rep(j, n+10) dp[i][j] = -1;
    ll ans = 0;
    rep(i,n) {
        chmax(ans, sub(i,i,0));
    }
    cout << ans << endl;
}

int main(void){
    std::ifstream in("tmp_in");
    if (TEST) {
        std::cin.rdbuf(in.rdbuf());
        std::cout << std::fixed << std::setprecision(15);
    } else {
        std::cin.tie(nullptr);
        std::ios_base::sync_with_stdio(false);
        std::cout << std::fixed << std::setprecision(15);
    }
    Main();
}
accuracy: 1
time_ms: 40
memory_kb: 35056
final_rank: 6

code_snippet: bool TEST = false;

using namespace std;
#include<bits/stdc++.h>
#include<fstream>

#define rep(i,n) for(int (i)=0;(i)<(ll)(n);i++)
#define repr(i,n) for(int (i)=(ll)(n)-1;(i)>=0;i--)
#define range(i,start,end,step) for(int (i)=start;(i)<(ll)(end);(i)+=(step))

#define dump(x)  cerr << "Line " << __LINE__ << ": " <<  #x << " = " << (x) << "\n";
#define spa << " " <<
#define fi first
#define se second
#define all(a)  (a).begin(),(a).end()
#define allr(a)  (a).rbegin(),(a).rend()

using ld = long double;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<ld, ld>;
 
template<typename T> using V = vector<T>;
template<typename T> using VV = V<V<T>>;
template<typename T, typename T2> using P = pair<T, T2>;
template<typename T, typename T2> using M = map<T, T2>;
template<typename T> using S = set<T>;
template<typename T, typename T2> using UM = unordered_map<T, T2>;
template<typename T> using PQ = priority_queue<T, V<T>, greater<T>>;
template<typename T> using rPQ = priority_queue<T, V<T>, less<T>>;
template<typename T> vector<T> make_vec(size_t n, T a) { return vector<T>(n, a); }
template<typename... Ts> auto make_vec(size_t n, Ts... ts) { return vector<decltype(make_vec(ts...))>(n, make_vec(ts...)); }
template<class SS, class T> ostream& operator << (ostream& os, const pair<SS, T> v){os << "(" << v.first << ", " << v.second << ")"; return os;}
template<typename T> ostream& operator<<(ostream &os, const vector<T> &v) { for (auto &e : v) os << e << ' '; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<vector<T>> &v){ for(auto &e : v){os << e << "\n";} return os;}
struct fast_ios { fast_ios(){ cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
 
template <class T> void UNIQUE(vector<T> &x) {sort(ALL(x));x.erase(unique(ALL(x)), x.end());}
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
void fail() { cout << -1 << '\n'; exit(0); }
inline int popcount(const int x) { return __builtin_popcount(x); }
inline int popcount(const ll x) { return __builtin_popcountll(x); }
template<typename T> void debug(vector<vector<T>>&v){for(ll i=0;i<v.size();i++)
{cerr<<v[i][0];for(ll j=1;j<v[i].size();j++)cerr spa v[i][j];cerr<<"\n";}};
template<typename T> void debug(vector<T>&v){if(v.size()!=0)cerr<<v[0];
for(ll i=1;i<v.size();i++)cerr spa v[i];
cerr<<"\n";};
template<typename T> P<T,T> divmod(T a, T b) {return make_pair(a/b, a%b);}

const ll INF = (1ll<<62);
// const ld EPS   = 1e-10;
// const ld PI    = acos(-1.0);
const ll mod = (int)1e9 + 7;
//const ll mod = 998244353;


ll dp[2010][2010];
int n;
V<ll> a;

ll sub(int l, int r, bool f = 1) {
    l = (l+n)%n;
    r = (r+n)%n;
    ll res = 0;
    if (r==l && f) return 0;
    if (dp[l][r]>=0) return dp[l][r];
    else {
        int nl,nnl,nr,nnr;
        ll vl,vl2,vr,vr2;
        nl = (n+l-1)%n;
        nnl = (n+l-2)%n;
        nr = (r)%n;
        nnr = (r+1)%n;
        vl = a[nl];
        vl2 = a[nnl];
        vr = a[nr];
        vr2 = a[nnr];
        if ((r-l+2*n)%n==n-1) {
            assert(vl==vr);
            // cout << l spa r spa vl spa vr;
            res = vl;
        } else {
            if (vl2<vr) chmax(res, sub(l-1,r+1) + vl);
            else chmax(res, sub(l-2,r,1) + vl);
            if (vl<vr2) chmax(res, sub(l, r+2) + vr);
            else chmax(res, sub(l-1,r+1) + vr);
        }
    }
    // cout << l spa r spa res << endl;
    dp[l][r] = res;
    return res;
}
void Main(){
    cin >> n;
    a = V<ll>(n);
    rep(i,n) cin >> a[i];
    rep(i,2*n+10) rep(j, 2*n+10) dp[i][j] = -1;
    ll ans = 0;
    rep(i,n) {
        chmax(ans, sub(i,i,0));
    }
    cout << ans << endl;
}

int main(void){
    std::ifstream in("tmp_in");
    if (TEST) {
        std::cin.rdbuf(in.rdbuf());
        std::cout << std::fixed << std::setprecision(15);
    } else {
        std::cin.tie(nullptr);
        std::ios_base::sync_with_stdio(false);
        std::cout << std::fixed << std::setprecision(15);
    }
    Main();
}
accuracy: 0.7575757575757576
time_ms: 10
memory_kb: 34924
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, N) for (ll i = 0; i < N; i++)
ll N;
ll dp[2020][2020][2] = {};
ll A[2020];

ll rec(ll l, ll r, ll turn, ll cnt)
{
  if (cnt == N)
    return 0;
  if (dp[l][r][turn] != -1)
    return dp[l][r][turn];
  ll ret;
 
  ll lm = (l - 1 < 0) ? N - 1 : l - 1;
  ll rp = (r + 1 >= N) ? 0 : r + 1;
  
  if (turn == 1)
  {
    if (A[lm] > A[rp])
    { 
      ret = rec(lm, r, 0, cnt+1);
    }
    else
      ret = rec(l, rp, 0, cnt+1);
  }
  else
  { 
    ret = max(rec(lm, r, 1, cnt+1) + A[lm] , rec(l, rp, 1, cnt+1) + A[rp]);
    /*
    if (A[lm] > A[rp])
    {
      ret = rec(lm, r, 1, cnt++) + A[lm];
    }
    else
      ret = rec(l, rp, 1, cnt++) + A[rp];*/
  }  
  return dp[l][r][turn] = ret;
}

int main()
{
  cin >> N;
  rep(i, N) cin >> A[i];
  rep(i, N) rep(j, N)
  {
    dp[i][j][0] = dp[i][j][1] = -1;
  }
  ll maxv = 0;

  rep(i, N)
  {
    maxv = max(maxv, A[i] + rec(i, i, 1, 1));
  }
  cout << maxv << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 66400
final_rank: 7

code_snippet: #include<bits/stdc++.h>
#define rep(i, x) for(ll i = 0; i < x; i++)
#define rep2(i, x) for(ll i = 1; i <= x; i++)
using ll = long long;
using namespace std;
const ll INF = 1000000000000000000;

ll n, a[2005], dp[4005][4005];
ll solve(ll l, ll r) {//区間[l, r)を食べた
	if (dp[l][r] != -1) { return dp[l][r]; }
	if (r - l == 1) { return dp[l][r] = a[l % n]; }
	if ((r - l) % 2 == 0) {
		ll ans = 0 - INF;
		if (a[(l - 1 + n) % n] <= a[(r - 1) % n]) { ans = max(ans, solve(l, r - 1)); }
		if (a[l % n] >= a[r % n]) { ans = max(ans, solve(l + 1, r)); }
		return dp[l][r] = ans;
	}
	return dp[l][r] = max(solve(l, r - 1) + a[(r - 1) % n], solve(l + 1, r) + a[l % n]);
}

int main() {
	//input
	rep(i, 4005) { rep(j, 4005) { dp[i][j] = -1; } }
	cin >> n;
	rep(i, n) { cin >> a[i]; }
	ll ans = 0;
	rep(i, n) {
		ans = max(ans, solve(i, i + n));
	}
	cout << ans << endl;
	return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 128512
final_rank: 19

code_snippet: #include<cstdio>
#include<algorithm>
using namespace std;
long long dp[2001][2001],mx;
int main(void)
{
	int n,i,j,w,x,a[2001];
	scanf("%d",&n);
	for(i=1;i<=2000;i++){
		for(j=1;j<=2000;j++){
			dp[i][j]=-1;
		}
	}
	for(i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		dp[1][i]=a[i];
	}
	for(i=1;i<n;i++){
		for(j=1;j<=n;j++){
		if(dp[i][j]!=-1&&i%2==0){
			w=j-1;
			if(w==0)	w=n;
			dp[i+1][w]=max(dp[i+1][w],dp[i][j]+a[w]);
			x=i+j;
			if(x>n)	x=x-n;
			dp[i+1][j]=max(dp[i+1][j],dp[i][j]+a[x]);
		}
		if(dp[i][j]!=-1&&i%2!=0){
			w=j-1;
			if(w==0)	w=n;
			x=i+j;
			if(x>n)	x=x-n;
			if(a[w]>a[x]){
				dp[i+1][w]=max(dp[i+1][w],dp[i][j]);
			}
			else{
				dp[i+1][j]=max(dp[i+1][j],dp[i][j]);
			}
		}
		}
	}
	mx=-1;
	for(i=1;i<=n;i++){
		if(mx<dp[n][i])	mx=dp[n][i];
	}
	printf("%lld\n",mx);
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 34036
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#include <algorithm>
#include <cmath>
#include <set>
#include <cstdio>
#include <vector>
#include <iostream>
#include <utility>
#include <queue>
#include <map>
#include <complex>
#define fir first
#define sec second
#define sz(s) (s).size()
#define pb push_back
#define get(n) scanf("%d",&n);
#define gets(s) string s;cin >> (s);
#define prfi(n) printf("%d", &n);
#define prfd(n) printf("%lf", &n);
#define All(s) (s).begin(), (s).end()
#define rep(i,j) for(int (i)=0;(i)<(j);(i)++)
#define For(i,j,k) for(int (i)=(j);(i)<(k);(i)++)
#define drep(i,j) for(int (i)=(j);(i)>=0;(i)--)
#define Ford(i,j,k) for(int (i)=(j);i>=(k);i--)
#define fore(c,v) for(auto (c): (v))
#define lp for(int __=0;__<n;i++)
#define mem(a,b) memset(a,b,sizeof(a));
#define dump(x)  std::cout << #x << " = " << (x) << std::endl;
#define debug(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;
using ull = unsigned long long int;
using ll = long long;
using ld = long double;
using pii = std::pair<int,int>;
using pll = std::pair<ll, ll>;
using vi = std::vector<int> ;
using vvi = std::vector<vi> ;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vd = std::vector<double> ;
using vvd = std::vector<vd> ;
using qi = std::queue<int> ;
using vpii = std::vector<std::pair<int, int> >;
using vpll = std::vector<pll>;
using namespace std;

const int Mod = (1e9) + 7;
const int INF = 1e9 + 19;
const ll INFL = 1e18 + 19;
const int dx[] = {-1, 0, 0, 1};
const int dy[] = {0, -1, 1, 0};
const int dx2[] = {-1, -1, -1, 0, 0, 0, 1, 1, 1};
const int dy2[] = {1, 0, -1, 1, 0, -1, 1, 0, -1};
const double EPS = 1e-10;
//_____________________________________Templates_________________________________________//

template<class T1, class T2> inline void chmin(T1 &a, T2 b){if(a > b) a = b;}
template<class T1, class T2> inline void chmax(T1 &a, T2 b){if(a < b) a = b;}
template<class T> inline void pri(T a){cout << a << endl;}
template<class Z> using vec = vector<Z>;
template<class T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
//mainly use for dynamic prog
template<class T1, class T2>
void update(T1 &a, T2 b){
  a += b;
  if(a > Mod) a %= Mod;
}

inline void IN(void){
  return;
}

template <typename First, typename... Rest>
void IN(First& first, Rest&... rest){
  cin >> first;
  IN(rest...);
  return;
}

inline void OUT(void){
  cout << "\n";
  return;
}

template <typename First, typename... Rest>
void OUT(First first, Rest... rest){
  cout << first << " ";
  OUT(rest...);
  return;
}

bool pairsort(pll pl, pll pr){
  if(pl.first == pr.first)return pl.second > pr.second;
  return pl.first < pr.first;
}

int cntbit(ll a,int n,int j){int res = 0;For(i,j,n){if(a>>i & 1){res++;}}return res;}
vector<int> make_bit(int a){vector<int> res; for(int i=31;i>=0;i--)if(a&(1<<i))res.pb(i);return res;}
bool stdbit(int a, int b){return a&(1 << b); }
int GCD(int a, int b){if(b > a)return GCD(b,a);if(a%b == 0)return b;else return GCD(b, a%b);}
int LCM(int a, int b){return a*b/GCD(a,b);}
int roundup(int a, int b){if(a % b == 0)return a/b;else return (a+b)/b;}
int rounddown(int a, int b){if(a%b == 0)return a/b;else {return (a-b)/b;}}
ll pow(ll a, ll n){ll res = 1;while(n > 0){if(n&1)res *= a; a *= a; n = n >> 1;}return res;}
ll GetDiviserCount(ll N)//約数の個数
{
  ll res = 1;
  For(i,2,sqrt(N)+1)
  {
    ll cnt = 0;
    while(N%i == 0)
    {
      cnt++;
      N /= i;
    }
    res *= (cnt + 1);
    if(N == 1)break;
  }
  if(N != 1)res *= 2;
  return res;
}
vll GetDivisor(ll N)//約数列挙
{
  vll res;
  for(ll i = 1;i*i <= N;i++)
  {
    if(N%i == 0)
    {
      res.pb(i);
      if(i*i != N)res.pb(N/i);
    }
  }
  sort(All(res));
  return res;
}

struct Modint
{
  using ll = long long int;
  ll x;
  Modint(ll x=0) :x((x%Mod+Mod)%Mod) {}
  Modint operator - ()
  {
   return Modint(-x);
  }
  Modint& operator +=(Modint a)
  {
    x += a.x;
    if(x >= Mod)x -= Mod;
    return *this;
  }
  Modint& operator -=(Modint a)
  {
   if(x < a.x)x += Mod;
   x -= a.x;
   return *this;
  }
  Modint& operator *=(Modint a)
  {
    (x *= a.x) %= Mod;
    return *this;
  }
  Modint operator + (Modint a)
  {
    Modint b(*this);
    b += a;
    return b;
  }
  Modint operator - (Modint a)
  {
    Modint b(*this);
    b -= a;
    return b;
  }
  Modint operator * (Modint a)
  {
    Modint b(*this);
    b *= a;
    return b;
  }
  long long int EXTGCD(long long int a, long long int b, long long int &x, long long int &y)
  {
    if(b==0)
    {
      x = 1;
      y = 0;
      return a;
    }
    long long int g = EXTGCD(b,a%b,y,x);
    y -= (a/b)*x;
    return g;
  }
  Modint inverse()
  {
    long long int a,b;
    EXTGCD(x,Mod,a,b);
    a %= Mod;
    return a;
  }
  Modint pow(ll a)
  {
    Modint res = 1;
    Modint b = x;
    while(a > 0)
    {
      if(a & 1)res *= b;
      a = a >> 1;
      b *= b;
    }
    return res;
  }
  friend ostream& operator<<(ostream& os, const Modint& a);
};
ostream& operator<< (ostream& os, const Modint& a)
{
  os << a.x;
  return os;
}
struct combination
{
  vector<Modint> fact,ifact;
  combination(int n) : fact(n+1), ifact(n+1)
  {
    fact[0] = 1;
    for(int i=1;i<=n;i++)fact[i] = fact[i-1] * i;
    ifact[n] = fact[n].inverse();
    for(int i=n;i>=1;i--)ifact[i-1] = ifact[i] * i;
  }
  Modint operator() (int n,int k)
  {
    return fact[n]*ifact[n-k]*ifact[k];
  }
};
using vm = vector<Modint>;
using vvm = vector<vm>;
template<class Z>
struct MyMatrix
{
  using mat = MyMatrix<Z>;
  vector<vector<Z>> m_dat;
  int m_h;
  int m_w;
  MyMatrix(int h, int w) : m_h(h), m_w(w) ,m_dat(h,vector<Z>(w)) {}
  vector<Z> &operator[] (int idx)
  {
    return m_dat[idx];
  }
  mat Multiple(mat &a)
  {
    mat C(m_h, a.m_w);
    for(int i=0;i<m_h;i++)
    {
      for(int j=0;j<a.m_w;j++)
      {
        for(int k=0;k<m_w;k++)
        {
         C[i][j] += m_dat[i][k] * a[k][j];
        }
      }
    }
    return C;
  }
  mat Pow(ll x)
  {
    mat B(m_h,m_w);
    for(int i=0;i<m_h;i++)
    {
      B[i][i] = 1;
    }
    mat A = *this;
    while(x > 0)
    {
      if(x&1)B = B.Multiple(A);
      A = A.Multiple(A);
      x = x >> 1;
    }
    return B;
  }
  //friend ostream& operator<<(ostream &os, const mat &A);
};
/*
template<class Z>
ostream& operator<<(ostream &os, Matrix<Z>& A)
{
  for(int i=0;i<A.m_h;i++)
  {
    for(int j=0;j<A.m_w;j++)
    {
      os << A[i][j] << " ";
    }
    os << endl;
  }
  return os;
}
*/
template<class T>
using mat = MyMatrix<T>;
//_____________________　following sorce code_________________________//
const int max_n = 3 * (1e5) + 1;
const int max_m = 83 * (1e5) + 1;

int n,m,k;
ll N;
int h,w;
string S;
int a,b,c;
vi v;
int ans;
double x,y,z;
vector<int> G[1010101];
vi arr;
vvll dp;
ll rec(int l,int r)
{
  if(dp[l][r] >= 0)return dp[l][r];
  if(l == r)return dp[l][r] = 0;
  int x = r-l;
  ll res = 0;
  if(x%2 == n%2)
  {
    chmax(res,max(rec(l+1,r)+arr[l], rec(l,r-1)+arr[r-1]));
  }
  else 
  {
    if(arr[l] > arr[r-1])
    {
      res = rec(l+1,r);
    }
    else
    {
      res = rec(l,r-1);
    }
  }
  //OUT(l,r);
  dp[l][r] = res;
  //cout << "dp[" << l << "][" << r << "] = " << dp[l][r] << endl;
  return dp[l][r];
}

void solve()
{
  IN(n);
  rep(i,n)
  {
    IN(a);
    arr.push_back(a);
  }
  rep(i,n)
  {
    arr.push_back(arr[i]);
  }
  ll ans = 0;
  dp = vvll(n+n+3,vll(n+n+3,-1));
  rep(i,n)
  {
    ll res = rec(i,i+n);
    //dump(res);
    chmax(ans,res);
  }
  pri(ans);
}

signed main (int argc, char* argv[]) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int cases=1;
  //IN(cases);
  while(cases--)solve();
  //pri(ans);
  //for(auto c : ans){cout << c << endl;}
  //cout << fixed << setprecision(15) << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 152052
final_rank: 17

code_snippet: #include <iostream>
using namespace std;
typedef long long ll;
ll dp[4000][4000],n,a,b,ans,x;
ll f(ll a,ll b,ll cnt){
    if(a==b&&cnt%2==0)return 0;
    if(dp[a][b]>0&&cnt%2==1)return dp[a][b];
    if(cnt%2==1){
        x=max(f(a+1,b,cnt+1)+dp[a][a],f(a,b-1,cnt+1)+dp[b][b]);
        dp[a][b]=x;
        return x;
    }
    else{
        if(dp[a][a]>dp[b][b])x=f(a+1,b,cnt+1);
        else x=f(a,b-1,cnt+1);
        dp[a][b]=x;
        return x;
    }
}
int main(void){
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a;
        dp[i][i]=a;
        dp[i+n][i+n]=a;
    }
    for(int i=0;i<n;i++){
        ans=max(ans,dp[i][i]+f(i+1,i+n-1,0));
    }
    cout<<ans<<endl;
}
accuracy: 1
time_ms: 60
memory_kb: 65084
final_rank: 8