Problem p00448 (C++) — buggy submission, verdict: Time Limit Exceeded

//
// Created by Tnecesoc on 2017/4/14.
//

#include <bitset>
#include <stdio.h>

using namespace std;

const int MAX_R = 20;
const int MAX_C = 10000 + 10;

int field[MAX_R][MAX_C];

bitset<MAX_C> toast[MAX_R];

void solve(int fr, int r, int c, int &min) {

  if (fr >= r) {

    int sum = 0;

    for (int i = 0; i < c; ++i) {
      int row_sum = 0;
      for (int j = 0; j < r; ++j) {
        if (toast[j][i]) {
          row_sum++;
        }
      }

      sum += row_sum < r - row_sum ? row_sum : r - row_sum;
    }

    if (min > sum) {
      min = sum;
    }

    return;
  } else {

    solve(fr + 1, r, c, min);

    toast[fr].flip();

    solve(fr + 1, r, c, min);
  }
}

int main() {

  int r, c;
  while (~scanf("%d %d", &r, &c), r | c) {
    for (int i = 0; i < r; ++i) {
      for (int j = 0; j < c; ++j) {
        scanf("%d", &field[i][j]);
        toast[i].set((size_t)j, (bool)field[i][j]);
      }
    }

    int ans = 0x7fffffff;
    solve(0, r, c, ans);
    printf("%d\\n", r * c - ans);
  }

  return 0;
}

Error: TLE

Fixed submission:

//
// Created by Tnecesoc on 2017/4/14.
//

#include <stdio.h>

const int MAX_R = 20;
const int MAX_C = 10000 + 10;

int field[MAX_R][MAX_C];

int row_sum[MAX_R];

void flipR(int fr, int c, int &sum) {

  sum -= row_sum[fr];

  row_sum[fr] = 0;

  for (int i = 0; i < c; ++i) {
    field[fr][i] = !field[fr][i];
    row_sum[fr] += field[fr][i];
  }

  sum += row_sum[fr];
}

void flipC(int fc, int r, int &sum) {

  for (int i = 0; i < r; ++i) {

    field[i][fc] = !field[i][fc];

    if (field[i][fc]) {
      row_sum[i]++;
      sum++;
    } else {
      row_sum[i]--;
      sum--;
    }
  }
}

// r = c.
void solve(int fr, int fc, int r, int c, int &sum, int &min) {

  if (fc >= r && fc >= c) {

    if (min > sum) {
      min = sum;
    }

  } else if (fr < r && fc >= c) {

    int original = sum;

    flipR(fr, c, sum);

    if (sum > original) {
      flipR(fr, c, sum);
    }

    solve(fr + 1, fc, r, c, sum, min);

  } else if (fr >= r && fc < c) {

    int original = sum;

    solve(fr, fc + 1, r, c, sum, min);

    flipC(fc, r, sum);

    if (sum > original) {
      flipC(fc, r, sum);
    }

    solve(fr, fc + 1, r, c, sum, min);

  } else if (fr < r && fc < c) {

    solve(fr + 1, fc + 1, r, c, sum, min);

    flipC(fc, r, sum);

    solve(fr + 1, fc + 1, r, c, sum, min);

    flipR(fr, c, sum);

    solve(fr + 1, fc + 1, r, c, sum, min);

    flipC(fc, r, sum);

    solve(fr + 1, fc + 1, r, c, sum, min);
  }
}

// r > c.
void solveR(int fr, int fc, int r, int c, int &sum, int &min) {

  if (fc >= r && fc >= c) {

    if (min > sum) {
      min = sum;
    }

  } else if (fr < r && fc >= c) {

    int original = sum;

    flipR(fr, c, sum);

    if (sum > original) {
      flipR(fr, c, sum);
    }

    solve(fr + 1, fc, r, c, sum, min);

  } else if (fr >= r && fc < c) {

    int original = sum;

    solve(fr, fc + 1, r, c, sum, min);

    flipC(fc, r, sum);

    if (sum > original) {
      flipC(fc, r, sum);
    }

    solve(fr, fc + 1, r, c, sum, min);

  } else if (fr < r && fc < c) {

    int original = sum;

    flipR(fr, c, sum);

    if (sum > original) {
      flipR(fr, c, sum);
    }

    solve(fr + 1, fc + 1, r, c, sum, min);

    flipC(fc, r, sum);

    solve(fr + 1, fc + 1, r, c, sum, min);

    flipC(fc, r, sum);
  }
}

// r < c.
void solveC(int fr, int fc, int r, int c, int &sum, int &min) {

  if (fc >= r && fc >= c) {

    if (min > sum) {
      min = sum;
    }

  } else if (fr < r && fc >= c) {

    int original = sum;

    flipR(fr, c, sum);

    if (sum > original) {
      flipR(fr, c, sum);
    }

    solve(fr + 1, fc, r, c, sum, min);

  } else if (fr >= r && fc < c) {

    int original = sum;

    solve(fr, fc + 1, r, c, sum, min);

    flipC(fc, r, sum);

    if (sum > original) {
      flipC(fc, r, sum);
    }

    solve(fr, fc + 1, r, c, sum, min);

  } else if (fr < r && fc < c) {

    int original = sum;

    flipC(fc, r, sum);

    if (sum > original) {
      flipR(fc, r, sum);
    }

    //        solve(fr + 1, fc + 1, r, c, sum, min);

    flipR(fr, c, sum);

    solve(fr + 1, fc + 1, r, c, sum, min);

    flipR(fr, c, sum);
  }
}

int main() {

  int r, c, sum;
  while (~scanf("%d %d", &r, &c)) {

    sum = 0;

    for (int i = 0; i < r; ++i) {
      row_sum[i] = 0;
      for (int j = 0; j < c; ++j) {
        scanf("%d", &field[i][j]);
        row_sum[i] += field[i][j];
      }
      sum += row_sum[i];
    }

    int ans = 0x7fffffff;

    if (r < c) {
      solveC(0, 0, r, c, sum, ans);
    } else if (r > c) {
      solveR(0, 0, r, c, sum, ans);
    } else {
      solve(0, 0, r, c, sum, ans);
    }

    printf("%d\\n", r * c - ans);
  }

  return 0;
}