Problem p03580 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
// #define FUCKOJ
const int MAXN = 5e5 + 100;
int re[MAXN][5];
int num[MAXN];
int Max4(int a, int b, int c, int d) { return max(max(a, b), max(c, d)); }
int Max3(int a, int b, int c) { return Max4(a, b, c, 0); }

int op1(int i, int po) {
  int tmp = Max3(re[i - 1][0], re[i - 1][2], re[i - 1][3]);
  return max(tmp, re[i - 1][1]);
}

int op2(int i, int po) {
  int tmp = Max3(re[i - 1][0] + num[i - 1], re[i - 1][2] + 1, re[i - 1][3]);
  if (po == 1)
    return max(tmp, re[i - 1][1]);
  else
    return max(tmp, re[i - 1][1] + num[i - 1] - 1);
}

int op3(int i, int po) {
  int tmp = Max3(re[i - 1][0] + max(num[i - 1], num[i] - 1),
                 re[i - 1][2] + num[i] - 1, re[i - 1][3]);
  if (po == 1)
    return max(tmp, re[i - 1][1]);
  else
    return max(tmp, re[i - 1][1] + max(num[i] - 1, num[i - 1] - 1));
}

int op4(int i, int po) {
  int tmp = Max3(re[i - 1][0] + max(num[i - 1], num[i]), re[i - 1][2] + num[i],
                 re[i - 1][3]);
  if (po == 1)
    return max(tmp, re[i - 1][1]);
  else
    return max(tmp, re[i - 1][1] + max(num[i - 1] - 1, num[i]));
}

int N;
int dp(int n) {
  if (n <= 1)
    return num[0] = 0;
#ifdef FUCKOJ
  cout << "now:";
  for (int i = 0; i < n; ++i)
    cout << num[i];
  cout << endl;
#endif
  memset(re, 0, sizeof re);
  for (int i = 1, j; i < n; ++i) {
    re[i][0] = op1(i, num[i - 1]);
    re[i][1] = op2(i, num[i - 1]);
    re[i][2] = op3(i, num[i - 1]);
    re[i][3] = op4(i, num[i - 1]);
    if (num[i] == 1)
      re[i][1] = re[i][3], re[i][2] = re[i][0];
  }
  for (int i = 0; i < n; ++i)
    num[i] = 0;

#ifdef FUCKOJ
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < 4; ++j)
      cout << re[i][j] << ((j == 3) ? "\n" : " ");
#endif

  int ans = Max4(re[n - 1][0], re[n - 1][1], re[n - 1][2], re[n - 1][3]);
#ifdef FUCKOJ
  cout << "ans:" << ans << endl;
#endif
  return ans;
}
char str[MAXN];

int main() {
  // int N;
  scanf("%d%s", &N, str);
  int cnt = 0;
  int now;
  int i = 0;
  int ans = 0;
  while (i < N) {

    if (str[i] == '0') {
      if (num[cnt] == 0)
        ans += dp(cnt), cnt = 0;
      else
        cnt++;
      //		cout<<cnt<<endl;
    } else
      num[cnt]++;
    i++;
  }
  if (num[cnt] == 0)
    ans += dp(cnt);
  else
    ans += dp(cnt + 1);
  printf("%d", ans);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
// #define FUCKOJ
const int MAXN = 5e5 + 100;
int re[MAXN][5];
int num[MAXN];
int Max4(int a, int b, int c, int d) { return max(max(a, b), max(c, d)); }
int Max3(int a, int b, int c) { return Max4(a, b, c, 0); }

int op1(int i, int po) {
  int tmp = Max3(re[i - 1][0], re[i - 1][2], re[i - 1][3]);
  return max(tmp, re[i - 1][1]);
}

int op2(int i, int po) {
  int tmp = Max3(re[i - 1][0] + num[i - 1], re[i - 1][2] + 1, re[i - 1][3]);
  if (po == 1)
    return max(tmp, re[i - 1][1]);
  else
    return max(tmp, re[i - 1][1] + num[i - 1] - 1);
}

int op3(int i, int po) {
  int tmp = Max3(re[i - 1][0] + max(num[i - 1], num[i] - 1),
                 re[i - 1][2] + num[i] - 1, re[i - 1][3]);
  if (po == 1)
    return max(tmp, re[i - 1][1]);
  else
    return max(tmp, re[i - 1][1] + max(num[i] - 1, num[i - 1] - 1));
}

int op4(int i, int po) {
  int tmp = Max3(re[i - 1][0] + max(num[i - 1], num[i]), re[i - 1][2] + num[i],
                 re[i - 1][3]);
  if (po == 1)
    return max(tmp, re[i - 1][1]);
  else
    return max(tmp, re[i - 1][1] + max(num[i - 1] - 1, num[i]));
}

int N;
int dp(int n) {
  if (n <= 1)
    return num[0] = 0;
#ifdef FUCKOJ
  cout << "now:";
  for (int i = 0; i < n; ++i)
    cout << num[i];
  cout << endl;
#endif
  // memset(re,0,sizeof re);
  // for(int i=0;i<4;++i)	re[0][i]=0;
  for (int i = 1, j; i < n; ++i) {
    re[i][0] = op1(i, num[i - 1]);
    re[i][1] = op2(i, num[i - 1]);
    re[i][2] = op3(i, num[i - 1]);
    re[i][3] = op4(i, num[i - 1]);
    if (num[i] == 1)
      re[i][1] = re[i][3], re[i][2] = re[i][0];
  }
  for (int i = 0; i < n; ++i)
    num[i] = 0;

#ifdef FUCKOJ
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < 4; ++j)
      cout << re[i][j] << ((j == 3) ? "\n" : " ");
#endif

  int ans = Max4(re[n - 1][0], re[n - 1][1], re[n - 1][2], re[n - 1][3]);
#ifdef FUCKOJ
  cout << "ans:" << ans << endl;
#endif
  return ans;
}
char str[MAXN];

int main() {
  // int N;
  scanf("%d%s", &N, str);
  int cnt = 0;
  int now;
  int i = 0;
  int ans = 0;
  while (i < N) {

    if (str[i] == '0') {
      if (num[cnt] == 0)
        ans += dp(cnt), cnt = 0;
      else
        cnt++;
      //		cout<<cnt<<endl;
    } else
      num[cnt]++;
    i++;
  }
  if (num[cnt] == 0)
    ans += dp(cnt);
  else
    ans += dp(cnt + 1);
  printf("%d", ans);
  return 0;
}