Problem p00709 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;

typedef long long ll;
typedef pair<int, int> P;

int w, h;
int p[11][11];
int cnt[11][11];
int res;

struct square {
  int x, y, si;
  square() {}
  square(int xx, int yy, int ss) {
    x = xx;
    y = yy;
    si = ss;
  }
  bool operator<(const square &s) const { return si < s.si; }
};

vector<square> sq;
vector<square> usq;

bool check(int s, int y, int x) {
  for (int i = y; i < y + s; i++) {
    for (int j = x; j < x + s; j++) {
      if (i >= h || j >= w)
        return false;
      if (p[i][j] == 0)
        return false;
    }
  }
  return true;
}

bool cover(square a, square b) {
  bool flag = false;
  bool flag2 = false;
  if (a.x <= b.x && b.x + b.si <= a.x + a.si)
    flag = true;
  if (a.y <= b.y && b.y + b.si <= a.y + a.si)
    flag2 = true;
  return (flag && flag2);
}

int hstar(int v) {
  int n = 0;
  int val[101];
  int c = 0;
  for (; v < usq.size(); v++) {
    val[c] = 0;
    for (int i = usq[v].x; i < usq[v].x + usq[v].si; i++) {
      for (int j = usq[v].y; j < usq[v].y + usq[v].si; j++) {
        if (p[j][i] == 1)
          val[c]++;
      }
    }
    c++;
  }
  int rest = 0;
  sort(val, val + c, greater<int>());
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      rest += p[i][j];
    }
  }
  int l = 0;
  for (l = 0; rest > 0; l++) {
    rest -= val[l];
  }
  return l;
}

bool empty() {
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (p[i][j] == 1)
        return false;
    }
  }
  return true;
}

void update(int v, int c) {
  for (int i = usq[v].x; i < usq[v].x + usq[v].si; i++) {
    for (int j = usq[v].y; j < usq[v].y + usq[v].si; j++) {
      cnt[j][i] += c;
    }
  }
}

void dfs(int v, int sum) {
  if (empty()) {
    res = min(sum, res);
    return;
  }
  if (v == (int)usq.size())
    return;
  if (sum + hstar(v) >= res)
    return;
  bool ok1 = false, ok2 = false;
  for (int i = usq[v].x; i < usq[v].x + usq[v].si; i++) {
    for (int j = usq[v].y; j < usq[v].y + usq[v].si; j++) {
      if (p[j][i] == 1) {
        ok1 = true;
        if (cnt[j][i] == 1)
          ok2 = true;
      }
    }
  }
  update(v, -1);
  if (ok1) {
    int tmp[11][11];
    memcpy(tmp, p, sizeof(p));
    for (int i = usq[v].x; i < usq[v].x + usq[v].si; i++) {
      for (int j = usq[v].y; j < usq[v].y + usq[v].si; j++) {
        p[j][i] = 0;
      }
    }
    dfs(v + 1, sum + 1);
    memcpy(p, tmp, sizeof(p));
  }
  if (!ok2) {
    dfs(v + 1, sum);
  }
  update(v, 1);
}

int main(void) {
  while (1) {
    scanf("%d%d", &w, &h);
    if (w == 0 && h == 0)
      break;
    sq.clear();
    usq.clear();
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        scanf("%d", &p[i][j]);
      }
    }
    for (int i = 1; i <= min(w, h); i++) {
      for (int j = 0; j < h; j++) {
        for (int k = 0; k < w; k++) {
          if (check(i, j, k)) {
            sq.push_back(square(k, j, i));
          }
        }
      }
    }
    sort(sq.begin(), sq.end());
    for (int i = (int)sq.size() - 1; i >= 0; i--) {
      bool flag = true;
      for (int j = 0; j < usq.size(); j++) {
        if (cover(usq[j], sq[i]))
          flag = false;
      }
      if (flag)
        usq.push_back(sq[i]);
    }
    memset(cnt, 0, sizeof(cnt));
    for (int i = 0; i < usq.size(); i++) {
      update(i, 1);
    }
    res = usq.size();
    dfs(0, 0);
    printf("%d\n", res);
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;

typedef long long ll;
typedef pair<int, int> P;

int w, h;
int p[11][11];
int cnt[11][11];
int res;

struct square {
  int x, y, si;
  square() {}
  square(int xx, int yy, int ss) {
    x = xx;
    y = yy;
    si = ss;
  }
  bool operator<(const square &s) const { return si < s.si; }
};

vector<square> sq;
vector<square> usq;

bool check(int s, int y, int x) {
  for (int i = y; i < y + s; i++) {
    for (int j = x; j < x + s; j++) {
      if (i >= h || j >= w)
        return false;
      if (p[i][j] == 0)
        return false;
    }
  }
  return true;
}

bool cover(square a, square b) {
  bool flag = false;
  bool flag2 = false;
  if (a.x <= b.x && b.x + b.si <= a.x + a.si)
    flag = true;
  if (a.y <= b.y && b.y + b.si <= a.y + a.si)
    flag2 = true;
  return (flag && flag2);
}

int hstar(int v) {
  int n = 0;
  int val[101];
  int c = 0;
  for (; v < usq.size(); v++) {
    val[c] = 0;
    for (int i = usq[v].x; i < usq[v].x + usq[v].si; i++) {
      for (int j = usq[v].y; j < usq[v].y + usq[v].si; j++) {
        if (p[j][i] == 1)
          val[c]++;
      }
    }
    c++;
  }
  int rest = 0;
  sort(val, val + c, greater<int>());
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      rest += p[i][j];
    }
  }
  int l = 0;
  for (l = 0; rest > 0; l++) {
    rest -= val[l];
  }
  return l;
}

bool empty() {
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (p[i][j] == 1)
        return false;
    }
  }
  return true;
}

void update(int v, int c) {
  for (int i = usq[v].x; i < usq[v].x + usq[v].si; i++) {
    for (int j = usq[v].y; j < usq[v].y + usq[v].si; j++) {
      cnt[j][i] += c;
    }
  }
}

void dfs(int v, int sum) {
  if (empty()) {
    res = min(sum, res);
    return;
  }
  if (v == (int)usq.size())
    return;
  if (sum + hstar(v) >= res)
    return;
  bool ok1 = false, ok2 = false;
  for (int i = usq[v].x; i < usq[v].x + usq[v].si; i++) {
    for (int j = usq[v].y; j < usq[v].y + usq[v].si; j++) {
      if (p[j][i] == 1) {
        ok1 = true;
        if (cnt[j][i] == 1)
          ok2 = true;
      }
    }
  }
  update(v, -1);
  if (ok1) {
    int tmp[11][11];
    memcpy(tmp, p, sizeof(p));
    for (int i = usq[v].x; i < usq[v].x + usq[v].si; i++) {
      for (int j = usq[v].y; j < usq[v].y + usq[v].si; j++) {
        p[j][i] = 0;
      }
    }
    dfs(v + 1, sum + 1);
    memcpy(p, tmp, sizeof(p));
  }
  if (!ok2) {
    dfs(v + 1, sum);
  }
  update(v, 1);
}

int main(void) {
  while (1) {
    scanf("%d%d", &w, &h);
    if (w == 0 && h == 0)
      break;
    sq.clear();
    usq.clear();
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        scanf("%d", &p[i][j]);
      }
    }
    for (int i = 1; i <= min(w, h); i++) {
      for (int j = 0; j < h; j++) {
        for (int k = 0; k < w; k++) {
          if (check(i, j, k)) {
            sq.push_back(square(k, j, i));
          }
        }
      }
    }
    sort(sq.begin(), sq.end());
    for (int i = (int)sq.size() - 1; i >= 0; i--) {
      bool flag = true;
      for (int j = 0; j < usq.size(); j++) {
        if (cover(usq[j], sq[i]))
          flag = false;
      }
      if (flag)
        usq.push_back(sq[i]);
    }
    memset(cnt, 0, sizeof(cnt));
    for (int i = 0; i < usq.size(); i++) {
      update(i, 1);
    }
    res = usq.size();
    sort(usq.begin(), usq.end());
    dfs(0, 0);
    printf("%d\n", res);
  }
  return 0;
}