Problem p02733 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#pragma warning(disable : 4996)

typedef long long ll;
#define MIN(a, b) ((a) > (b) ? (b) : (a))
#define MAX(a, b) ((a) < (b) ? (b) : (a))
#define LINF 9223300000000000000
#define LINF2 1223300000000000000
#define INF 2140000000
// const long long MOD = 1000000007;
// const long long MOD = 998244353;
long long MOD;

using namespace std;

char str[10][1005];
int s[12][12][1005];
int ne[12][12][1005];

void solve() {
  int h, w, K;
  scanf("%d%d%d", &h, &w, &K);
  int i, j, k;
  for (i = 0; i < h; i++) {
    scanf("%s", str[i]);
    for (j = 0; j < w; j++) {
      s[i][i + 1][j + 1] = s[i][i + 1][j] + (str[i][j] == '1' ? 1 : 0);
    }
  }

  for (k = 0; k <= w; k++) {
    for (i = 0; i <= h; i++) {
      for (j = i + 2; j <= h; j++) {
        s[i][j][k] = s[i][j - 1][k] + s[j - 1][j][k];
      }
    }
  }

  for (i = 0; i <= h; i++) {
    for (j = i + 1; j <= h; j++) {
      for (k = 0; k < w; k++) {
        int off =
            lower_bound(&s[i][j][k], &s[i][j][w + 1], s[i][j][k] + K + 1) -
            &s[i][j][0];
        off--;
        ne[i][j][k] = off;
      }
    }
  }

  int ans = INF;
  for (k = 0; k < (1 << (h - 1)); k++) {
    int cnt0 = 0;
    for (i = 1; i < h; i++) {
      if (k & (1 << (i - 1))) {
        cnt0++;
      }
    }

    int cnt = 0;
    int stt = 0;
    while (stt < w) {
      int min = INF;
      int prev = 0;
      for (i = 1; i <= h; i++) {
        if (i == h || (k & (1 << (i - 1)))) {
          int off = ne[prev][i][stt];
          min = MIN(min, off);
          prev = i;
        }
      }
      cnt++;
      stt = min;
    }
    // printf("%d ", cnt+cnt0-1);
    ans = MIN(ans, cnt + cnt0 - 1);
  }
  printf("%d\n", ans);

  return;
}

int main(int argc, char *argv[]) {
#if 1
  solve();
#else
  int T;
  scanf("%d", &T);
  while (T--) {
    solve();
  }
#endif
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#pragma warning(disable : 4996)

typedef long long ll;
#define MIN(a, b) ((a) > (b) ? (b) : (a))
#define MAX(a, b) ((a) < (b) ? (b) : (a))
#define LINF 9223300000000000000
#define LINF2 1223300000000000000
#define INF 2140000000
// const long long MOD = 1000000007;
// const long long MOD = 998244353;
long long MOD;

using namespace std;

char str[10][1005];
int s[12][12][1005];
int ne[12][12][1005];

void solve() {
  int h, w, K;
  scanf("%d%d%d", &h, &w, &K);
  int i, j, k;
  for (i = 0; i < h; i++) {
    scanf("%s", str[i]);
    for (j = 0; j < w; j++) {
      s[i][i + 1][j + 1] = s[i][i + 1][j] + (str[i][j] == '1' ? 1 : 0);
    }
  }

  for (k = 0; k <= w; k++) {
    for (i = 0; i <= h; i++) {
      for (j = i + 2; j <= h; j++) {
        s[i][j][k] = s[i][j - 1][k] + s[j - 1][j][k];
      }
    }
  }

  for (i = 0; i <= h; i++) {
    for (j = i + 1; j <= h; j++) {
      for (k = 0; k < w; k++) {
        int off =
            lower_bound(&s[i][j][k], &s[i][j][w + 1], s[i][j][k] + K + 1) -
            &s[i][j][0];
        off--;
        ne[i][j][k] = off;
      }
    }
  }

  int ans = INF;
  for (k = 0; k < (1 << (h - 1)); k++) {
    int cnt0 = 0;
    for (i = 1; i < h; i++) {
      if (k & (1 << (i - 1))) {
        cnt0++;
      }
    }

    int cnt = 0;
    int stt = 0;
    while (stt < w) {
      int min = INF;
      int prev = 0;
      for (i = 1; i <= h; i++) {
        if (i == h || (k & (1 << (i - 1)))) {
          int off = ne[prev][i][stt];
          min = MIN(min, off);
          prev = i;
        }
      }
      cnt++;
      if (min <= stt) {
        cnt = INF;
        break;
      }
      stt = min;
    }
    // printf("%d ", cnt+cnt0-1);
    ans = MIN(ans, cnt + cnt0 - 1);
  }
  printf("%d\n", ans);

  return;
}

int main(int argc, char *argv[]) {
#if 1
  solve();
#else
  int T;
  scanf("%d", &T);
  while (T--) {
    solve();
  }
#endif
  return 0;
}