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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

int W, H;
int POW[21], dp[1048576], next_dp[1048576];
int table[20][20];
vector<int> V;
int case_num = 1;

void recursive(int array[], int index) {

  if (index == W) {
    int code = 0;
    for (int i = 0; i < W; i++) {
      if (array[i] == 1)
        code += POW[i];
    }
    V.push_back(code);
    return;
  }

  if (array[index - 1] == 1) {
    int next_array[W];
    for (int i = 0; i < index; i++)
      next_array[i] = array[i];
    next_array[index] = 0;
    recursive(next_array, index + 1);
  } else {

    int next_array1[W];
    for (int i = 0; i < index; i++)
      next_array1[i] = array[i];
    next_array1[index] = 1;
    recursive(next_array1, index + 1);

    int next_array2[W];
    for (int i = 0; i < index; i++)
      next_array2[i] = array[i];
    next_array2[index] = 0;
    recursive(next_array2, index + 1);
  }
}

void func() {

  scanf("%d %d", &W, &H);
  if (W > H) {

    for (int row = 0; row < H; row++) {
      for (int col = 0; col < W; col++)
        scanf("%d", &table[col][row]);
    }
    swap(W, H);
  } else {
    for (int row = 0; row < H; row++) {
      for (int col = 0; col < W; col++)
        scanf("%d", &table[row][col]);
    }
  }

  int first_array0[W], first_array1[W];

  V.clear();

  first_array0[0] = 0;
  recursive(first_array0, 1);
  first_array1[0] = 1;
  recursive(first_array1, 1);

  sort(V.begin(), V.end());
  V.erase(unique(V.begin(), V.end()), V.end());

  for (int i = 0; i < V.size(); i++) {
    dp[V[i]] = 0;
    next_dp[V[i]] = 0;
  }

  int state, sum, maximum;

  for (int row = 0; row < H; row++) {

    for (int i = 0; i < V.size(); i++) {
      state = V[i];
      sum = 0;
      for (int loop = 0; loop < W; loop++) {
        if (state & (1 << loop)) {
          sum += table[row][loop];
        }
      }
      next_dp[state] = sum;

      maximum = 0;
      for (int k = 0; k < V.size(); k++) {
        if ((state & V[k]) == 0) {
          maximum = max(maximum, dp[V[k]]);
        }
      }
      next_dp[state] += maximum;
    }
    for (int i = 0; i < V.size(); i++) {
      dp[V[i]] = next_dp[V[i]];
    }
  }

  int ans = 0;
  for (int i = 0; i < V.size(); i++) {
    ans = max(ans, dp[V[i]]);
  }

  printf("Case %d: %d\\n", case_num++, ans);
}

int main() {

  for (int i = 0; i < 21; i++)
    POW[i] = pow(2, i);

  int data_set;
  scanf("%d", &data_set);

  for (int i = 0; i < data_set; i++)
    func();

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

int W, H;
int POW[21], dp[1048576], next_dp[1048576];
int table[20][20];
vector<int> V[21];
int case_num = 1;

void recursive(int array[], int index, int length) {

  if (index == length) {
    int code = 0;
    for (int i = 0; i < length; i++) {
      if (array[i] == 1)
        code += POW[i];
    }
    V[length].push_back(code);
    return;
  }

  if (array[index - 1] == 1) {
    int next_array[length];
    for (int i = 0; i < index; i++)
      next_array[i] = array[i];
    next_array[index] = 0;
    recursive(next_array, index + 1, length);
  } else {

    int next_array1[length];
    for (int i = 0; i < index; i++)
      next_array1[i] = array[i];
    next_array1[index] = 1;
    recursive(next_array1, index + 1, length);

    int next_array2[length];
    for (int i = 0; i < index; i++)
      next_array2[i] = array[i];
    next_array2[index] = 0;
    recursive(next_array2, index + 1, length);
  }
}

void func() {

  scanf("%d %d", &W, &H);
  if (W > H) {

    for (int row = 0; row < H; row++) {
      for (int col = 0; col < W; col++)
        scanf("%d", &table[col][row]);
    }
    swap(W, H);
  } else {
    for (int row = 0; row < H; row++) {
      for (int col = 0; col < W; col++)
        scanf("%d", &table[row][col]);
    }
  }

  for (int i = 0; i < V[W].size(); i++) {
    dp[V[W][i]] = 0;
    next_dp[V[W][i]] = 0;
  }

  int state, sum, maximum;

  for (int row = 0; row < H; row++) {

    for (int i = 0; i < V[W].size(); i++) {
      state = V[W][i];
      sum = 0;
      for (int loop = 0; loop < W; loop++) {
        if (state & (1 << loop)) {
          sum += table[row][loop];
        }
      }
      next_dp[state] = sum;

      maximum = 0;

      for (int k = 0; k < V[W].size(); k++) {
        if ((state & V[W][k]) == 0) {
          maximum = max(maximum, dp[V[W][k]]);
        }
      }
      next_dp[state] += maximum;
    }
    for (int i = 0; i < V[W].size(); i++) {
      dp[V[W][i]] = next_dp[V[W][i]];
    }
  }

  int ans = 0;
  for (int i = 0; i < V[W].size(); i++) {
    ans = max(ans, dp[V[W][i]]);
  }

  printf("Case %d: %d\\n", case_num++, ans);
}

void make_V() {

  for (int length = 1; length <= 20; length++) {

    int first_array0[length], first_array1[length];

    first_array0[0] = 0;
    recursive(first_array0, 1, length);
    first_array1[0] = 1;
    recursive(first_array1, 1, length);

    sort(V[length].begin(), V[length].end());
    V[length].erase(unique(V[length].begin(), V[length].end()),
                    V[length].end());
  }
}

int main() {

  for (int i = 0; i < 21; i++)
    POW[i] = pow(2, i);

  int data_set;
  scanf("%d", &data_set);

  make_V();

  for (int i = 0; i < data_set; i++)
    func();

  return 0;
}