Problem p00709 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = int(a) - 1; i >= int(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1 << (n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
const int inf = 1 << 28;
int h, w;

int board[10];
int len[15][15];

int min_res = 0;
int dfs(int y, int x, int d, int remain) {
  if (d + (remain ? 1 : 0) > min_res)
    return inf;

  if (y == h) {
    if (min_res > d)
      min_res = d;
    return d;
  }

  if (x >= w)
    return dfs(y + 1, 0, d, remain);

  if (len[y][x] == 0)
    return dfs(y, x + 1, d, remain);

  int ret = inf;
  if ((board[y] & bit(x)) == 0) {
    int cur = dfs(y, x + 1, d, remain);
    if (ret > cur)
      ret = cur;
  }

  int tboard[10], l = len[y][x];
  rep(i, y, y + l) tboard[i] = board[i];

  int nremain = remain;
  int mask = ((1 << l) - 1) << x;
  rep(a, y, y + l) {
    nremain -= popcount(board[a] & mask);
    board[a] &= (1023 ^ mask);
  }

  if (remain != nremain) {
    int cur = dfs(y, x + 1, d + 1, nremain);
    if (ret > cur)
      ret = cur;
  }

  rep(i, y, y + l) board[i] = tboard[i];
  return ret;
}

int main(void) {
  while (1) {
    scanf("%d %d", &w, &h);
    if (w == 0)
      break;

    rep(i, h) {
      board[i] = 0;
      rep(j, w) {
        int tmp;
        scanf("%d ", &tmp);
        board[i] |= (tmp << j);
      }
    }

    rep(i, h) rep(j, w) {
      len[i][j] = 0;
      if ((board[i] & bit(j)) == 0)
        continue;
      len[i][j] = min(h - i, w - j);
      const int l = len[i][j];
      rep(a, i, i + l) rep(b, j, j + l) if ((board[a] & bit(b)) == 0)
          len[i][j] = min(len[i][j], max(a - i, b - j));
    }

    int num[10][10], sy[10][10], sx[10][10];
    rep(i, h) rep(j, w) num[i][j] = 0;
    rep(i, h) rep(j, w) {
      const int l = len[i][j];
      rep(a, i, i + l) rep(b, j, j + l) num[a][b]++, sy[a][b] = i, sx[a][b] = j;
    }

    int add = 0;
    rep(i, h) rep(j, w) {
      if (num[i][j] != 1)
        continue;
      const int cy = sy[i][j], cx = sx[i][j], l = len[cy][cx],
                mask = ((1 << l) - 1) << cx;
      rep(a, cy, cy + l) board[a] &= (1023 ^ mask);
      len[cy][cx] = 0, add++;
    }

    int remain = 0;
    rep(i, h) remain += popcount(board[i]);
    min_res = min(21, remain);
    printf("%d\n", dfs(0, 0, 0, remain) + add);
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = int(a) - 1; i >= int(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1 << (n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
const int inf = 1 << 28;
int h, w;

int board[10];
int len[15][15];

int min_res = 0;
int dfs(int y, int x, int d, int remain) {
  if (d + (remain ? 1 : 0) > min_res)
    return inf;

  if (y == h) {
    if (min_res > d)
      min_res = d;
    return d;
  }

  if (x >= w)
    return dfs(y + 1, 0, d, remain);

  if (len[y][x] == 0)
    return dfs(y, x + 1, d, remain);

  int ret = inf;
  if ((board[y] & bit(x)) == 0) {
    int cur = dfs(y, x + 1, d, remain);
    if (ret > cur)
      ret = cur;
  }

  int tboard[10], l = len[y][x];
  rep(i, y, y + l) tboard[i] = board[i];

  int nremain = remain;
  int mask = ((1 << l) - 1) << x;
  rep(a, y, y + l) {
    nremain -= popcount(board[a] & mask);
    board[a] &= (1023 ^ mask);
  }

  if (remain != nremain) {
    int cur = dfs(y, x + 1, d + 1, nremain);
    if (ret > cur)
      ret = cur;
  }

  rep(i, y, y + l) board[i] = tboard[i];
  return ret;
}

int main(void) {
  while (1) {
    scanf("%d %d", &w, &h);
    if (w == 0)
      break;

    rep(i, h) {
      board[i] = 0;
      rep(j, w) {
        int tmp;
        scanf("%d ", &tmp);
        board[i] |= (tmp << j);
      }
    }

    rep(i, h) rep(j, w) {
      len[i][j] = 0;
      if ((board[i] & bit(j)) == 0)
        continue;
      len[i][j] = min(h - i, w - j);
      const int l = len[i][j];
      rep(a, i, i + l) rep(b, j, j + l) if ((board[a] & bit(b)) == 0)
          len[i][j] = min(len[i][j], max(a - i, b - j));
    }

    int num[10][10], sy[10][10], sx[10][10];
    rep(i, h) rep(j, w) num[i][j] = 0;
    rep(i, h) rep(j, w) {
      const int l = len[i][j];
      rep(a, i, i + l) rep(b, j, j + l) num[a][b]++, sy[a][b] = i, sx[a][b] = j;
    }

    int add = 0;
    rep(i, h) rep(j, w) {
      if (num[i][j] != 1)
        continue;
      const int cy = sy[i][j], cx = sx[i][j], l = len[cy][cx],
                mask = ((1 << l) - 1) << cx;
      rep(a, cy, cy + l) board[a] &= (1023 ^ mask);
      len[cy][cx] = 0, add++;
    }

    int remain = 0;
    rep(i, h) remain += popcount(board[i]);
    min_res = min(20, remain);
    int ans = dfs(0, 0, 0, remain);
    if (ans == inf)
      ans = 21;
    printf("%d\n", ans + add);
  }
  return 0;
}