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

#include <bits/stdc++.h>
#define EPS 1e-10
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

int w, h;
int fie[2][5][5];
vector<P> G[6 * 6 * 6 * 6 * 6];
int valid[61];
int ok[6];
int curfie[5][5];
int id[10005];

void init(int v, int a, int b, int col) {
  memset(curfie, -1, sizeof(curfie));
  for (int i = 0; i < w; i++) {
    for (int j = ok[i]; j < h; j++) {
      curfie[j][i] = fie[1][j][i];
    }
  }
  for (int i = 0; i <= a; i++) {
    for (int j = 0; j <= b; j++) {
      curfie[i][j] = col;
    }
  }
  int nok[6];
  for (int i = w - 1; i >= 0; i--) {
    nok[i] = h;
    for (int j = h - 1; j >= 0; j--) {
      if (i < w - 1 && nok[i + 1] == nok[i])
        break;
      if (curfie[j][i] != fie[1][j][i])
        break;
      nok[i]--;
    }
  }
  int nxt = 0;
  for (int i = w - 1; i >= 0; i--) {
    nxt *= h + 1;
    nxt += nok[i];
  }
  G[v].push_back(P(nxt, (a + 1) * (b + 1)));
}

typedef vector<double> vec;
typedef vector<vec> mat;

vec gauss_jordan(const mat &A, const vec &b) {
  int N = A.size();
  mat B(N, vec(N + 1));
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      B[i][j] = A[i][j];
    }
  }
  for (int i = 0; i < N; i++) {
    B[i][N] = b[i];
  }
  for (int i = 0; i < N; i++) {
    int pivot = i;
    for (int j = i; j < N; j++) {
      if (fabs(B[j][i]) > fabs(B[pivot][i]))
        pivot = j;
    }
    swap(B[i], B[pivot]);
    if (fabs(B[i][i]) < EPS)
      continue;
    for (int j = i + 1; j <= N; j++) {
      B[i][j] /= B[i][i];
    }
    for (int j = 0; j < N; j++) {
      if (i != j) {
        for (int k = i + 1; k <= N; k++) {
          B[j][k] -= B[j][i] * B[i][k];
        }
      }
    }
  }
  vec x(N);
  for (int i = 0; i < N; i++) {
    x[i] = B[i][N];
  }
  return x;
}

void solve() {
  for (int i = 0; i < 6 * 6 * 6 * 6 * 6; i++) {
    G[i].clear();
  }
  int siz = 1;
  for (int i = 0; i < w; i++) {
    siz *= (h + 1);
  }
  int siz2 = 0;
  memset(id, -1, sizeof(id));
  for (int i = 0; i < siz; i++) {
    int v = i;
    bool flag = false;
    for (int j = 0; j < w; j++) {
      ok[j] = v % (h + 1);
      if (j > 0 && ok[j - 1] < ok[j])
        flag = true;
      v /= h + 1;
    }
    if (flag)
      continue;
    id[i] = siz2;
    siz2++;
    for (int a = 0; a < h; a++) {
      for (int b = 0; b < w; b++) {
        for (int c = 0; c < 2; c++) {
          init(i, a, b, c);
        }
      }
    }
  }
  mat eff(siz2, vec(siz2, 0.0));
  for (int i = 0; i < siz; i++) {
    if (id[i] == -1)
      continue;
    int v = id[i];
    if (v == 0) {
      eff[v][0] = 1.0;
    } else {
      for (int k = 0; k < G[i].size(); k++) {
        eff[v][id[G[i][k].first]] += (double)1.0 / G[i].size();
      }
    }
  }
  double ads = 0.0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      ads += (i + 1.0) * (j + 1.0);
    }
  }
  ads /= h * w;
  vec vo(siz2, 0.0);
  for (int i = 1; i < siz2; i++) {
    for (int j = 0; j < siz2; j++) {
      eff[i][j] = -eff[i][j];
    }
    eff[i][i] += 1.0;
    vo[i] = ads;
  }
  vec res = gauss_jordan(eff, vo);
  int nok[6];
  for (int i = w - 1; i >= 0; i--) {
    nok[i] = h;
    for (int j = h - 1; j >= 0; j--) {
      if (i < w - 1 && nok[i + 1] == nok[i])
        break;
      if (fie[1][j][i] != fie[0][j][i])
        break;
      nok[i]--;
    }
  }
  int resid = 0;
  for (int i = w - 1; i >= 0; i--) {
    resid *= h + 1;
    resid += nok[i];
  }
  printf("%.10f\\n", res[id[resid]]);
}

int main(void) {
  while (1) {
    scanf("%d%d", &h, &w);
    if (h == 0 && w == 0)
      break;
    for (int k = 0; k < 2; k++) {
      for (int i = 0; i < h; i++) {
        string str;
        cin >> str;
        for (int j = 0; j < w; j++) {
          if (str[j] == 'W') {
            fie[k][i][j] = 0;
          } else {
            fie[k][i][j] = 1;
          }
        }
      }
    }
    solve();
  }
  return 0;
}


Error: TLE

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 fie[2][5][5];
double dp[2][6 * 6 * 6 * 6 * 6];
vector<P> G[6 * 6 * 6 * 6 * 6];
int ok[6];
int curfie[5][5];

void init(int v, int a, int b, int col) {
  memset(curfie, -1, sizeof(curfie));
  for (int i = 0; i < w; i++) {
    for (int j = ok[i]; j < h; j++) {
      curfie[j][i] = fie[1][j][i];
    }
  }
  for (int i = 0; i <= a; i++) {
    for (int j = 0; j <= b; j++) {
      curfie[i][j] = col;
    }
  }
  int nok[6];
  for (int i = w - 1; i >= 0; i--) {
    nok[i] = h;
    for (int j = h - 1; j >= 0; j--) {
      if (i < w - 1 && nok[i + 1] == nok[i])
        break;
      if (curfie[j][i] != fie[1][j][i])
        break;
      nok[i]--;
    }
  }
  int nxt = 0;
  for (int i = w - 1; i >= 0; i--) {
    nxt *= h + 1;
    nxt += nok[i];
  }
  G[v].push_back(P(nxt, (a + 1) * (b + 1)));
}

void solve() {
  for (int i = 0; i < 6 * 6 * 6 * 6 * 6; i++) {
    dp[0][i] = 0;
    dp[1][i] = 0;
    G[i].clear();
  }
  int siz = 1;
  for (int i = 0; i < w; i++) {
    siz *= (h + 1);
  }
  for (int i = 0; i < siz; i++) {
    int v = i;
    bool flag = false;
    for (int j = 0; j < w; j++) {
      ok[j] = v % (h + 1);
      v /= h + 1;
    }
    for (int a = 0; a < h; a++) {
      for (int b = 0; b < w; b++) {
        for (int c = 0; c < 2; c++) {
          init(i, a, b, c);
        }
      }
    }
  }
  int cur = 0, nxt = 1;
  for (int i = 0; i < 1001; i++) {
    for (int j = 0; j < siz; j++) {
      if (j == 0)
        continue;
      int cnt = 0;
      int su = 0;
      double sum = 0;
      for (int k = 0; k < G[j].size(); k++) {
        sum += (double)G[j][k].second / G[j].size();
        if (G[j][k].first != j)
          sum += dp[cur][G[j][k].first] / G[j].size();
        else
          cnt++;
      }
      dp[nxt][j] = sum * G[j].size() / (G[j].size() - cnt);
    }
    swap(cur, nxt);
    // for(int j=0;j<siz;j++){
    // if(i%100==0)printf("%.2f ",dp[cur][j]);
    //}
    // if(i%100==0)printf("\\n");
  }
  int nok[6];
  for (int i = w - 1; i >= 0; i--) {
    nok[i] = h;
    for (int j = h - 1; j >= 0; j--) {
      if (i < w - 1 && nok[i + 1] == nok[i])
        break;
      if (fie[1][j][i] != fie[0][j][i])
        break;
      nok[i]--;
    }
  }
  int res = 0;
  for (int i = w - 1; i >= 0; i--) {
    res *= h + 1;
    res += nok[i];
  }
  printf("%.10f\\n", dp[cur][res]);
}

int main(void) {
  while (1) {
    scanf("%d%d", &h, &w);
    if (h == 0 && w == 0)
      break;
    for (int k = 0; k < 2; k++) {
      for (int i = 0; i < h; i++) {
        string str;
        cin >> str;
        for (int j = 0; j < w; j++) {
          if (str[j] == 'W') {
            fie[k][i][j] = 0;
          } else {
            fie[k][i][j] = 1;
          }
        }
      }
    }
    solve();
  }
  return 0;
}