Problem:
お菓子の分割
問題
長さ N ミリメートルの棒状のお菓子が 1 本ある(ここで N は偶数). 2 人の JOI
関係者が,このお菓子を複数本に切断して,合計 N/2 ミリメートルずつに分けること
にした.
理由は不明であるが,このお菓子は場所によって切断のしやすさが異なっている.
2 人は,お菓子を左から 1 ミリメートルごとに調べ,各場所で切断に何秒かかるか
を割り出した.2 人がお菓子を分けるための切断にかかる秒数の最小値を求めるプ
ログラムを作成せよ.
入力
入力の 1 行目には,棒の長さ N(2 ≤ N ≤ 10000 ,ただし N は偶数) が書かれてい
る.入力の i + 1 行目 (1 ≤ i ≤ N − 1) には,左端から i ミリメートル目の場所の切
断にかかる秒数を表す整数 ti (1 ≤ ti ≤ 10000) が書かれている.切断可能な場所が
N − 1 箇所であることに注意せよ.
採点用データのうち,配点の 5% 分については,高々 2 カ所を切断することで最
小値を実現でき,10% 分については,高々 3 カ所を切断することで最小値を実現で
きる.配点の 20% 分については,N ≤ 20 である.
出力
出力は2 人がお菓子を分るための切断にかかる秒数の最小値を含む 1 行からなる.
入出力例
入力例 1
6
1
8
12
6
2
出力例 1
7
この場合,左端から 1 ミリメートルと 4 ミリメートルの場所で切断するとかかる
秒数が最小となる.かかる秒数は 1 秒と 6 秒で,合計 7 秒である.
上記問題文と自動審判に使われるデータは、
情報オリンピック日本委員会
が作成し公開している問題文と採点用テストデータです。

Submitted solutions:

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int n, a[100000], dp[5005][2];
int main() {
	cin >> n; for (int i = 0; i < n - 1; i++)cin >> a[i];
	for (int i = 0; i < 5005; i++) { dp[i][0] = 999999999; dp[i][1] = 999999999; }
	dp[n / 2][0] = 0; dp[n / 2][1] = 0;
	for (int i = n - 1; i >= 0; i--) {
		for (int j = 0; j <= n / 2; j++) {
			dp[j][0] = min(dp[j][0], dp[j][1] + a[i]);
			dp[j][1] = min(dp[j + 1][1], dp[j + 1][0] + a[i]);
		}
	}
	cout << min(dp[0][0], dp[0][1]) << endl;
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3520
final_rank: 4

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

static const int INF = 1e9;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    cin >> N;
    vector<int> t(N);    // t[1..N-1] に切断コスト
    for(int i = 1; i < N; i++){
        cin >> t[i];
    }

    int half = N / 2;
    // dp[k][b]: 現在位置 i まで決めて、A(=1)の数が k、ラベルの色が b(0= B, 1= A) のときの最小コスト
    // N は最大 10000 で half=5000。i ごとには k=0..half のみ必要なのでメモリ ≃ 5001×2 をローリング配列で回す。
    vector<int> dp0(half+1, INF), dp1(half+1, INF);

    // i=1 の初期化：コスト0 でラベル B(0) or A(1) を許す
    dp0[0] = 0;            // ラベルB で Aの数 0 の場合
    if(half >= 1) dp1[1] = 0;  // ラベルA で Aの数 1 の場合

    // i=1 から i=N-1 まで遷移
    for(int i = 1; i < N; i++){
        vector<int> ndp0(half+1, INF), ndp1(half+1, INF);
        for(int k = 0; k <= half; k++){
            int c0 = dp0[k];
            int c1 = dp1[k];
            if(c0 < INF){
                // 旧ラベル B(0)→ 新ラベル B(0): 境界切断なし
                ndp0[k] = min(ndp0[k], c0);
                // 旧ラベル B(0)→ 新ラベル A(1): 境界 i で切断→ コスト +t[i]
                if(k+1 <= half)
                    ndp1[k+1] = min(ndp1[k+1], c0 + t[i]);
            }
            if(c1 < INF){
                // 旧ラベル A(1)→ 新ラベル B(0): 切断
                ndp0[k] = min(ndp0[k], c1 + t[i]);
                // 旧ラベル A(1)→ 新ラベル A(1): そのまま
                if(k+1 <= half)
                    ndp1[k+1] = min(ndp1[k+1], c1);
            }
        }
        dp0.swap(ndp0);
        dp1.swap(ndp1);
    }

    // 最終的に A の数 half, ラベル B/A いずれでも良いので最小値を取る
    int ans = min(dp0[half], dp1[half]);
    cout << ans << "\n";
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 3584
final_rank: 11

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

int main() {
  const int INF = 1000000000;
  int n, c;
  vector<vector<vector<int>>> dp(2, vector<vector<int>>(5002, vector<int>(2, INF)));

  dp[1][1][0] = 0;
  dp[1][0][1] = 0;
  cin >> n;
  
  for (int i = 2; i <= n; i++) {
    int s = i % 2, t = 1 - s;
    cin >> c;
    
    dp[s][0][0] = INF; // move out of the loop
    for (int j = 1; j <= n / 2; j++) {
      dp[s][j][0] = min(dp[t][j - 1][0], dp[t][j - 1][1] + c);
      dp[s][j][1] = min(dp[t][j][0] + c, dp[t][j][1]);
    }
  }
  cout << min(dp[0][n / 2][0], dp[0][n / 2][1]) << endl;
  return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3828
final_rank: 15

code_snippet: #include <iostream>
using namespace std;
int main() {
  const int INF = 1000000000;
  int n, c;
  static int dp[2][5002][2]; // Reduced size of dp array
  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 5002; j++) {
      dp[i][j][0] = INF;
      dp[i][j][1] = INF;
    }
  dp[1][1][0] = 0;
  dp[1][0][1] = 0;
  scanf("%d", &n);
  int s, t;
  for (int i = 2; i <= n; i++) {
    s = i % 2;
    t = 1 - s; // Compute s and t outside the loop
    scanf("%d", &c);
    for (int j = 0; j <= n / 2; j++) {
      if (j == 0)
        dp[s][j][0] = INF;
      else
        dp[s][j][0] = min(dp[t][j - 1][0], dp[t][j - 1][1] + c);
      dp[s][j][1] = min(dp[t][j][0] + c, dp[t][j][1]);
    }
  }
  printf("%d\n", min(dp[0][n / 2][0], dp[0][n / 2][1]));
}
accuracy: 1
time_ms: 40
memory_kb: 3632
final_rank: 10

code_snippet: #include <iostream>
using namespace std;

int main() {
  const int INF = 1000000000;
  int n, c;
  static int dp0[5002][2], dp1[5002][2];
  
  // Initialization
  for (int j = 0; j < 5002; j++) {
    dp0[j][0] = INF;
    dp0[j][1] = INF;
    dp1[j][0] = INF;
    dp1[j][1] = INF;
  }
  dp1[1][0] = 0;
  dp1[0][1] = 0;

  // Read input
  scanf("%d", &n);
  for (int i = 2; i <= n; i++) {
    int s = i % 2, t = 1 - s;
    scanf("%d", &c);
    for (int j = 0; j <= n / 2; j++) {
      if (j == 0)
        (s ? dp1 : dp0)[j][0] = INF;
      else
        (s ? dp1 : dp0)[j][0] = min((t ? dp1 : dp0)[j - 1][0], (t ? dp1 : dp0)[j - 1][1] + c);
      (s ? dp1 : dp0)[j][1] = min((t ? dp1 : dp0)[j][0] + c, (t ? dp1 : dp0)[j][1]);
    }
  }
  
  // Output result
  printf("%d\n", min(dp0[n / 2][0], dp0[n / 2][1]));
}
accuracy: 1
time_ms: 60
memory_kb: 3632
final_rank: 12

code_snippet: #include <cstdio>
#include <cstring>
using namespace std;
int n;
int t[10002];
int dp[2][5002][2];

int solve() {
  memset(dp, -1, sizeof(dp));
  dp[0][1][0] = dp[0][0][1] = 0;
  for (int i = 1; i < n; i++) {
    int cur = i & 1;
    int pre = 1 - cur;
    memset(dp[cur], -1, sizeof(dp[cur]));
    for (int j = 0; j <= n / 2; j++) {
      for (int p = 0; p < 2; p++) {
        if (dp[pre][j][p] == -1)
          continue;
        for (int next = 0; next < 2; next++) {
          if (p == next) {
            if (next == 0 && (dp[cur][j + 1][next] == -1 || dp[cur][j + 1][next] > dp[pre][j][p]))
              dp[cur][j + 1][next] = dp[pre][j][p];
            else if (dp[cur][j][next] == -1 || dp[cur][j][next] > dp[pre][j][p])
              dp[cur][j][next] = dp[pre][j][p];
          } else {
            if (next == 0 && (dp[cur][j + 1][next] == -1 || dp[cur][j + 1][next] > dp[pre][j][p] + t[i - 1]))
              dp[cur][j + 1][next] = dp[pre][j][p] + t[i - 1];
            else if (dp[cur][j][next] == -1 || dp[cur][j][next] > dp[pre][j][p] + t[i - 1])
              dp[cur][j][next] = dp[pre][j][p] + t[i - 1];
          }
        }
      }
    }
  }
  int final = n & 1;
  if (dp[final][n / 2][0] == -1) return dp[final][n / 2][1];
  if (dp[final][n / 2][1] == -1) return dp[final][n / 2][0];
  return dp[final][n / 2][0] > dp[final][n / 2][1] ? dp[final][n / 2][1] : dp[final][n / 2][0];
}

int main() {
  scanf("%d", &n);
  for (int i = 0; i < n - 1; i++) {
    scanf("%d", &t[i]);
  }
  printf("%d\n", solve());
}
accuracy: 0.1
time_ms: 290
memory_kb: 2856
final_rank: 18

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

int n;
int t[10002];
int dp[2][5002][2];

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

  memset(dp, -1, sizeof(dp));
  int cur = 0, pre = 1;
  dp[cur][1][0] = dp[cur][0][1] = 0;

  for (int i = 1; i < n; i++) {
    swap(cur, pre);
    memset(dp[cur], -1, sizeof(dp[cur]));
    for (int j = 0; j <= n / 2; j++) {
      for (int pre_state = 0; pre_state < 2; pre_state++) {
        if (dp[pre][j][pre_state] != -1) {
          int val0 = dp[pre][j][pre_state] + (pre_state == 0 ? 0 : t[i - 1]);
          dp[cur][j + 1][0] = dp[cur][j + 1][0] != -1 ? min(val0, dp[cur][j + 1][0]) : val0;
          int val1 = dp[pre][j][pre_state] + (pre_state == 1 ? 0 : t[i - 1]);
          dp[cur][j][1] = dp[cur][j][1] != -1 ? min(val1, dp[cur][j][1]) : val1;
        }
      }
    }
  }

  int ans = dp[cur][n / 2][0] != -1 ? dp[cur][n / 2][0] : dp[cur][n / 2][1];
  if (dp[cur][n / 2][0] != -1 && dp[cur][n / 2][1] != -1) {
    ans = min(dp[cur][n / 2][0], dp[cur][n / 2][1]);
  }
  printf("%d\n", ans);
}
accuracy: 1
time_ms: 240
memory_kb: 3328
final_rank: 3

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

int main() {
  const int INF = 1000000000;
  int n, c;
  vector<vector<vector<int>>> dp(2, vector<vector<int>>(5000 + 2, vector<int>(2, INF)));

  dp[1][1][0] = 0;
  dp[1][0][1] = 0;

  scanf("%d", &n);

  for (int i = 2; i <= n; i++) {
    int s = i % 2;
    int t = 1 - s;
    scanf("%d", &c);

    dp[s][0][0] = INF;

    for (int j = 1; j <= n / 2; j++) {
      dp[s][j][0] = min(dp[t][j - 1][0], dp[t][j - 1][1] + c);
      dp[s][j][1] = min(dp[t][j][0] + c, dp[t][j][1]);
    }
  }

  printf("%d\n", min(dp[0][n / 2][0], dp[0][n / 2][1]));
}
accuracy: 1
time_ms: 90
memory_kb: 3968
final_rank: 16

code_snippet: #include <iostream>
using namespace std;

int main() {
  const unsigned int INF = 1000000000;
  unsigned int n, c;
  cin >> n;

  // Dynamic allocation of the dp array
  unsigned int*** dp = new unsigned int**[2];
  for (unsigned int i = 0; i < 2; i++) {
    dp[i] = new unsigned int*[n / 2 + 1];
    for (unsigned int j = 0; j <= n / 2; j++) {
      dp[i][j] = new unsigned int[2];
      dp[i][j][0] = INF;
      dp[i][j][1] = INF;
    }
  }

  dp[1][1][0] = 0;
  dp[1][0][1] = 0;

  for (unsigned int i = 2; i <= n; i++) {
    unsigned int s = i % 2;
    unsigned int t = 1 - s;
    cin >> c;

    // Optimized inner loop
    for (unsigned int j = 1; j <= n / 2; j++) {
      dp[s][j][0] = min(dp[t][j - 1][0], dp[t][j - 1][1] + c);
      dp[s][j][1] = min(dp[t][j][0] + c, dp[t][j][1]);
    }
  }

  cout << min(dp[0][n / 2][0], dp[0][n / 2][1]) << endl;

  // Freeing the dynamically allocated memory
  for (unsigned int i = 0; i < 2; i++) {
    for (unsigned int j = 0; j <= n / 2; j++) {
      delete[] dp[i][j];
    }
    delete[] dp[i];
  }
  delete[] dp;

  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3820
final_rank: 14

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

int n;
int t[10002];
int dp[5002][2], tmp[5002][2];

int minCost(const int &a, const int &b) {
  int result = a;
  if (result == -1 || (b != -1 && b < result)) {
    result = b;
  }
  return result;
}

int solve() {
  memset(tmp, -1, sizeof(tmp));
  tmp[1][0] = tmp[0][1] = 0;

  for (int i = 1; i < n; i++) {
    memset(dp, -1, sizeof(dp));

    for (int j = 0; j <= n / 2; j++) {
      for (int pre = 0; pre < 2; pre++) {
        if (tmp[j][pre] == -1)
          continue;
        for (int next = 0; next < 2; next++) {
          if (pre == next) {
            if (next == 0)
              dp[j + 1][next] = minCost(dp[j + 1][next], tmp[j][pre]);
            else
              dp[j][next] = minCost(dp[j][next], tmp[j][pre]);
          } else {
            if (next == 0)
              dp[j + 1][next] =
                  minCost(dp[j + 1][next], tmp[j][pre] + t[i - 1]);
            else
              dp[j][next] = minCost(dp[j][next], tmp[j][pre] + t[i - 1]);
          }
        }
      }
    }
    swap(dp, tmp);
  }

  return minCost(dp[n / 2][0], dp[n / 2][1]);
}

int main() {
  scanf("%d", &n);
  for (int i = 0; i < n - 1; i++) {
    scanf("%d", &t[i]);
  }
  printf("%d\n", solve());
}
accuracy: 0.1
time_ms: 360
memory_kb: 3316
final_rank: 19

code_snippet: #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n;
int *t;
int dp[5002][2], tmp[5002][2];
int minCost(const int &a, const int &b) {
  if (a == -1)
    return b;
  if (b == -1)
    return a;
  return a > b ? b : a;
}
int solve() {
  int half = n/2;
  memset(tmp, -1, sizeof(tmp));
  tmp[1][0] = tmp[0][1] = 0;
  for (int i = 1; i < n; i++) {
    for(int j = 0; j <= half; j++){
        dp[j][0] = dp[j][1] = -1;
    }
    for (int j = 0; j <= half; j++) {
      for (int pre = 0; pre < 2; pre++) {
        if (tmp[j][pre] == -1)
          continue;
        for (int next = 0; next < 2; next++) {
          if (pre == next) {
            if (next == 0)
              dp[j + 1][next] = minCost(dp[j + 1][next], tmp[j][pre]);
            else
              dp[j][next] = minCost(dp[j][next], tmp[j][pre]);
          } else {
            if (next == 0)
              dp[j + 1][next] =
                  minCost(dp[j + 1][next], tmp[j][pre] + t[i - 1]);
            else
              dp[j][next] = minCost(dp[j][next], tmp[j][pre] + t[i - 1]);
          }
        }
      }
    }
    swap(dp, tmp);
  }
  return minCost(tmp[half][0], tmp[half][1]);
}
int main() {
  scanf("%d", &n);
  t = new int[n-1];
  for (int i = 0; i < n - 1; i++) {
    scanf("%d", &t[i]);
  }
  printf("%d\n", solve());
  delete[] t;
}
accuracy: 1
time_ms: 400
memory_kb: 3336
final_rank: 13

code_snippet: #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n;
int t[10002];
int dp[5002][2], tmp[5002][2];
int minCost(const int &a, const int &b) {
  if (a == -1)
    return b;
  if (b == -1)
    return a;
  return a > b ? b : a;
}
int solve() {
  memset(tmp, -1, sizeof(tmp[0][0]) * ((n / 2) + 1) * 2);
  tmp[1][0] = tmp[0][1] = 0;
  for (int i = 1; i < n; i++) {
    memset(dp, -1, sizeof(dp[0][0]) * ((n / 2) + 1) * 2);
    for (int j = 0; j <= n / 2; j++) {
      for (int pre = 0; pre < 2; pre++) {
        if (tmp[j][pre] == -1)
          continue;
        for (int next = 0; next < 2; next++) {
          int cost = minCost(dp[j + (next == 0 ? 1 : 0)][next], tmp[j][pre] + (pre != next ? t[i - 1] : 0));
          dp[j + (next == 0 ? 1 : 0)][next] = cost;
        }
      }
    }
    std::copy(&dp[0][0], &dp[0][0] + (n / 2 + 1) * 2, &tmp[0][0]);
  }
  return minCost(dp[n / 2][0], dp[n / 2][1]);
}
int main() {
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    cin >> t[i];
  }
  cout << solve() << '\n';
}
accuracy: 1
time_ms: 200
memory_kb: 3264
final_rank: 2

code_snippet: #include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n;
int t[10002];
int dp[2][5002][2];
int minCost(const int &a, const int &b) {
  if (a == -1)
    return b;
  if (b == -1)
    return a;
  return a > b ? b : a;
}
int solve() {
  int cur = 0, pre = 1;
  memset(dp[cur], -1, sizeof(dp[cur]));
  dp[cur][1][0] = dp[cur][0][1] = 0;
  for (int i = 1; i < n; i++) {
    swap(cur, pre);
    memset(dp[cur], -1, sizeof(dp[cur]));
    for (int j = 0; j <= n / 2; j++) {
      for (int preState = 0; preState < 2; preState++) {
        if (dp[pre][j][preState] == -1)
          continue;
        for (int nextState = 0; nextState < 2; nextState++) {
          int cost = dp[pre][j][preState];
          if (preState != nextState)
            cost += t[i - 1];
          if (nextState == 0)
            dp[cur][j + 1][nextState] = minCost(dp[cur][j + 1][nextState], cost);
          else
            dp[cur][j][nextState] = minCost(dp[cur][j][nextState], cost);
        }
      }
    }
  }
  return minCost(dp[cur][n / 2][0], dp[cur][n / 2][1]);
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n - 1; i++) {
    scanf("%d", &t[i]);
  }
  printf("%d\n", solve());
}
accuracy: 1
time_ms: 370
memory_kb: 3336
final_rank: 9

code_snippet: #include <iostream>
using namespace std;
int main() {
  std::ios::sync_with_stdio(false);
  const int INF = 1000000000;
  int n, c;
  static int dp[2][5002][2];
  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 5002; j++) {
      dp[i][j][0] = INF;
      dp[i][j][1] = INF;
    }
  dp[1][1][0] = 0;
  dp[1][0][1] = 0;
  cin >> n;
  for (int i = 2; i <= n; i++) {
    int s = i % 2, t = 1 - s;
    cin >> c;
    for (int j = 0; j <= n / 2; j++) {
      int t_j_0 = dp[t][j][0], t_j_1 = dp[t][j][1], t_jm1_0 = dp[t][j - 1][0], t_jm1_1 = dp[t][j - 1][1];
      if (j == 0)
        dp[s][j][0] = INF;
      else
        dp[s][j][0] = min(t_jm1_0, t_jm1_1 + c);
      int t_j_0_c = t_j_0 + c;
      dp[s][j][1] = min(t_j_0_c, t_j_1);
    }
  }
  cout << min(dp[0][n / 2][0], dp[0][n / 2][1]) << "\n";
}
accuracy: 1
time_ms: 40
memory_kb: 3524
final_rank: 6

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

const int INF = 1000000000;
static int dp[2][5002][2];
int n, c;

int main() {
  for (int i = 0; i < 2; i++)
    for (int j = 0; j <= 5000; j++)
      dp[i][j][0] = dp[i][j][1] = INF;

  scanf("%d", &n);
  dp[1][0][0] = dp[1][0][1] = 0;
  bool flip = true;
  for (int i = 2; i <= n; i++) {
    flip = !flip;
    scanf("%d", &c);
    for (int j = 0; j <= n / 2; j++) {
      if (j == 0)
        dp[flip][j][0] = INF;
      else
        dp[flip][j][0] = min(dp[!flip][j - 1][0], dp[!flip][j - 1][1] + c);
      dp[flip][j][1] = min(dp[!flip][j][0] + c, dp[!flip][j][1]);
    }
  }
  printf("%d\n", min(dp[flip][n / 2][0], dp[flip][n / 2][1]));
  return 0;
}
accuracy: 0.05
time_ms: 40
memory_kb: 3040
final_rank: 20

code_snippet: #include <iostream>
using std::cin;
using std::cout;

const int INF = 1000000000;

int main() {
  int n, c;
  int dp[2][5002][2];
  
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 5002; j++) {
      dp[i][j][0] = INF;
      dp[i][j][1] = INF;
    }
  }
  
  dp[1][1][0] = 0;
  dp[1][0][1] = 0;
  
  cin >> n;
  
  for (int i = 2; i <= n; i++) {
    int s = i % 2;
    int t = 1 - s;
    
    cin >> c;
    
    for (int j = 0; j <= n / 2; j++) {
      if (j == 0) {
        dp[s][j][0] = INF;
      } else {
        dp[s][j][0] = dp[t][j - 1][0] < dp[t][j - 1][1] + c ? dp[t][j - 1][0] : dp[t][j - 1][1] + c;
      }
      
      dp[s][j][1] = dp[t][j][0] + c < dp[t][j][1] ? dp[t][j][0] + c : dp[t][j][1];
    }
  }
  
  cout << (dp[0][n / 2][0] < dp[0][n / 2][1] ? dp[0][n / 2][0] : dp[0][n / 2][1]) << "\n";
}
accuracy: 1
time_ms: 60
memory_kb: 3536
final_rank: 8

code_snippet: #include <iostream>
#include <algorithm>
using std::cin;
using std::cout;
using std::endl;
using std::min;

const int INF = 1000000000;

int main() {
  int n, c;
  static int dp[2][5000 + 2][2];

  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 5002; j++) {
      dp[i][j][0] = INF;
      dp[i][j][1] = INF;
    }

  dp[1][1][0] = 0;
  dp[1][0][1] = 0;

  cin >> n;

  for (int i = 2; i <= n; i++) {
    int s = i % 2, t = 1 - s;
    cin >> c;

    for (int j = 0; j <= n / 2; j++) {
      if (j == 0)
        dp[s][j][0] = INF;
      else
        dp[s][j][0] = min(dp[t][j - 1][0], dp[t][j - 1][1] + c);
      dp[s][j][1] = min(dp[t][j][0] + c, dp[t][j][1]);
    }
  }

  cout << min(dp[0][n / 2][0], dp[0][n / 2][1]) << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 3500
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vvvb = vector<vvb>;
#define all(A) A.begin(),A.end()
#define rep(i, n) for (ll i = 0; i < (ll) (n); i++)
template<class T>
bool chmax(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p < q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}
template<class T>
bool chmin(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p > q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}

int main() {

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

    int N;
    cin >> N;
    vector<int> A(N/2+1,20000);
    vector<int> B(N/2+1,20000);
    vector<int> NB(N/2+1,20000);
    vector<int> NA(N/2+1, 20000);
    A[0]=B[1] = 0;
    rep(j, N - 1) {
        int t;
        cin >> t;
        for(int i=max(0,N/2-(N-int(j))-3);i<=min(int(j),N/2);i++){
            
            NA[i]=min(A[i],B[i]+t);
            if (i == N/2)break;
            NB[i+1]=min(B[i],A[i]+t);
        }
        swap(B,NB);
        swap(A,NA);
    }
    cout << min(A[N / 2], B[N / 2]) << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 3532
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vvvb = vector<vvb>;
#define all(A) A.begin(),A.end()
#define rep(i, n) for (ll i = 0; i < (ll) (n); i++)
template<class T>
bool chmax(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p < q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}
template<class T>
bool chmin(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p > q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}

int main() {

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

    ll N;
    cin >> N;
    vector<vector<int>> A(2, vector<int>(2,20000));
    rep(i, 2)A[i][i] = 0;
    rep(j, N - 1) {
        int t;
        cin >> t;
        vector<vector<int>> NA(j+2, vector<int>(2, 20000));
        rep(i, j+1) {
            int a=min(A[i][0],A[i][1]+t);
            if(a<NA[i][0])NA[i][0]=a;
            if (i == N)break;
            a=min(A[i][1],A[i][0]+t);
            if(a<NA[i+1][1])NA[i+1][1]=a;
        }
        A = NA;
    }
    cout << min(A[N / 2][0], A[N / 2][1]) << endl;
}
accuracy: 1
time_ms: 2790
memory_kb: 5304
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
const int INF = (1<<29);
int n, t;
int dp[2][5005];
int main(){
    cin >> n;
    fill_n(*dp, 2*5005, INF);
    dp[1][0] = 0;
    dp[0][1] = 0;
    for(int i=0;i<n-1;i++){
        cin >> t;
        for(int j=n/2;j>0;j--){
            dp[1][j] = min(dp[1][j], dp[0][j]+t);
            dp[0][j] = min(dp[0][j-1], dp[1][j-1]+t);
        }
    }
    cout << dp[0][n/2] << endl;
    return(0);
}
accuracy: 1
time_ms: 60
memory_kb: 3148
final_rank: 1