Problem p02733 (C++)

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

/*-------------------Define Start-------------------*/
typedef bool BL;                // 布尔类型
typedef char SB;                // 有符号1字节,8位
typedef unsigned char UB;       // 无符号1字节,8位
typedef short SW;               // 有符号短整型,16位
typedef unsigned short UW;      // 无符号短整型,16位
typedef long SDW;               // 有符号整型,32位
typedef unsigned long UDW;      // 无符号整型,32位
typedef long long SLL;          // 有符号长整型,64位
typedef unsigned long long ULL; // 无符号长整型,64位
typedef char CH;                // 单个字符
typedef float R32;              // 单精度浮点数
typedef double R64;             // 双精度浮点数

#define Rep(i, n) for (register SDW i = 0; i < (n); ++i)
#define For(i, s, t) for (register SDW i = (s); i <= (t); ++i)
#define rFor(i, t, s) for (register SDW i = (t); i >= (s); --i)
#define foreach(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
#define ms0(a) memset(a, 0, sizeof(a))
#define msI(a) memset(a, 0x7f, sizeof(a))
#define LOWBIT(x) ((x) & (-x))

#define MP make_pair
#define PB push_back
#define ft first
#define sd second

#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl

const ULL mod = 1e9 + 7;    // 常用模数(可根据题目需要修改)
const ULL inf = 0x7fffffff; // 用来表示无限大
const ULL infLL = 0x7fffffffffffffffLL; // 用来表示无限大
/*-------------------Define End-------------------*/

const UDW maxN = 1e3 + 7;
SDW H, W, K;
SDW S[13][maxN];
SDW ans = inf;

SDW getSum(SDW x1, SDW y1, SDW x2, SDW y2) {
  return S[x2][y2] - S[x2][y1 - 1] - S[x1 - 1][y2] + S[x1 - 1][y1 - 1];
}

void input() {
  cin >> H >> W >> K;
  For(i, 1, H) {
    For(j, 1, W) {
      scanf("%1d", &S[i][j]);
      S[i][j] +=
          S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1]; // 记录为前缀和,方便计算
    }
  }
}

void solve() {
  // 枚举水平方向上的所有切法
  Rep(i, 1 << (H - 1)) {
    // 在竖直方向上采用贪心切法
    vector<SDW> pos; // 记录水平切的位置
    SDW tmp = i;
    SDW ret = __builtin_popcount(i);

    pos.PB(0);
    while (tmp) {
      SDW x = LOWBIT(tmp);
      tmp &= tmp - 1;

      pos.PB(__builtin_ctz(x) + 1);
    }
    pos.PB(H);

    SDW a = 1, b = 1;

    while (b <= W) {
      For(j, 1, pos.size() - 1) {
        if (getSum(pos[j - 1] + 1, a, pos[j], b) > K) {
          ++ret;
          a = b;
          --b;
          break;
        }
      }
      ++b;
    }

    ans = min(ans, ret);
  }
}

void output() { cout << ans << endl; }

int main() {
  input();
  solve();
  output();
  return 0;
}

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

/*-------------------Define Start-------------------*/
typedef bool BL;                // 布尔类型
typedef char SB;                // 有符号1字节,8位
typedef unsigned char UB;       // 无符号1字节,8位
typedef short SW;               // 有符号短整型,16位
typedef unsigned short UW;      // 无符号短整型,16位
typedef long SDW;               // 有符号整型,32位
typedef unsigned long UDW;      // 无符号整型,32位
typedef long long SLL;          // 有符号长整型,64位
typedef unsigned long long ULL; // 无符号长整型,64位
typedef char CH;                // 单个字符
typedef float R32;              // 单精度浮点数
typedef double R64;             // 双精度浮点数

#define Rep(i, n) for (register SDW i = 0; i < (n); ++i)
#define For(i, s, t) for (register SDW i = (s); i <= (t); ++i)
#define rFor(i, t, s) for (register SDW i = (t); i >= (s); --i)
#define foreach(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
#define ms0(a) memset(a, 0, sizeof(a))
#define msI(a) memset(a, 0x7f, sizeof(a))
#define LOWBIT(x) ((x) & (-x))

#define MP make_pair
#define PB push_back
#define ft first
#define sd second

#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl

const ULL mod = 1e9 + 7;    // 常用模数(可根据题目需要修改)
const ULL inf = 0x7fffffff; // 用来表示无限大
const ULL infLL = 0x7fffffffffffffffLL; // 用来表示无限大
/*-------------------Define End-------------------*/

const UDW maxN = 1e3 + 7;
SDW H, W, K;
SDW S[13][maxN];
SDW ans = inf;

SDW getSum(SDW x1, SDW y1, SDW x2, SDW y2) {
  return S[x2][y2] - S[x2][y1 - 1] - S[x1 - 1][y2] + S[x1 - 1][y1 - 1];
}

void input() {
  cin >> H >> W >> K;
  For(i, 1, H) {
    For(j, 1, W) {
      scanf("%1d", &S[i][j]);
      S[i][j] +=
          S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1]; // 记录为前缀和,方便计算
    }
  }
}

void solve() {
  // 枚举水平方向上的所有切法
  Rep(i, 1 << (H - 1)) {
    // 在竖直方向上采用贪心切法
    vector<SDW> pos; // 记录水平切的位置
    SDW tmp = i;
    SDW ret = __builtin_popcount(i);

    pos.PB(0);
    while (tmp) {
      SDW x = LOWBIT(tmp);
      tmp &= tmp - 1;

      pos.PB(__builtin_ctz(x) + 1);
    }
    pos.PB(H);

    SDW a = 1, b = 1;

    while (b <= W) {
      For(j, 1, pos.size() - 1) {
        if (getSum(pos[j - 1] + 1, a, pos[j], b) > K) {
          if (a == b) { // 无法切开的情况,直接跳出
            b = W + 1;
            ret = inf;
            break;
          } else {
            ++ret;
            a = b;
            --b;
            break;
          }
        }
      }
      ++b;
    }

    ans = min(ans, ret);
  }
}

void output() { cout << ans << endl; }

int main() {
  input();
  solve();
  output();
  return 0;
}