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

#include <bits/stdc++.h>

#define REP(i, a, b) for (int i = a, i##_end_ = b; i <= i##_end_; ++i)
#define DREP(i, a, b) for (int i = a, i##_end_ = b; i >= i##_end_; --i)
#define MREP(i, x) for (int i = beg[x], v; v = to[i], i; i = las[i])
#define debug(x) cout << #x << "=" << x << endl
#define fi first
#define se second
#define mk make_pair
#define pb push_back
#define y1 asdasd
typedef long long ll;

using namespace std;

void File() {
  freopen("haner.in", "r", stdin);
  freopen("haner.out", "w", stdout);
}

template <typename T> void read(T &_) {
  T __ = 0, mul = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-')
      mul = -1;
    ch = getchar();
  }
  while (isdigit(ch))
    __ = (__ << 1) + (__ << 3) + (ch ^ '0'), ch = getchar();
  _ = __ * mul;
}

const int maxn = 40 + 10;
const int inf = 0x3f3f3f3f;
int n, m, px, py, dp[maxn][maxn][maxn][maxn], sum[maxn][maxn], ans = inf;
char s[maxn][maxn];

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

template <typename T> void chkmin(T &_, T __) { _ = _ < __ ? _ : __; }

int main() {
  read(n);
  read(m);
  REP(i, 1, n) scanf("%s", s[i] + 1);
  REP(i, 1, n) {
    REP(j, 1, m) {
      if (s[i][j] == 'P') {
        px = i;
        py = j;
        s[i][j] = '+';
      }
      sum[i][j] =
          sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + (s[i][j] == '#');
      // cout<<sum[i][j]<<" ";
    }
    // cout<<endl;
  }
  memset(dp, 63, sizeof(dp));
  dp[1][1][n][m] = 0; // 代表将(1,1,n,m)这个矩形独立的最小代价为0。
  REP(x1, 1, n) REP(y1, 1, m) DREP(x2, n, x1) DREP(y2, m, y1) {
    if (x1 <= px && x2 >= px && y1 <= py && y2 >= py) {
      int w = dp[x1][y1][x2][y2];
      REP(x, x1, x2) REP(y, y1, y2) {
        int cost1 = S(x1, y1, x, y) + S(x + 1, y + 1, x2, y2);
        int cost2 = S(x1, y + 1, x, y2) + S(x + 1, y1, x2, y);
        chkmin(dp[x1][y + 1][x][y2], cost1 + w);
        chkmin(dp[x + 1][y1][x2][y], cost1 + w);
        chkmin(dp[x1][y1][x][y], cost2 + w);
        chkmin(dp[x + 1][y + 1][x2][y2], cost2 + w);
      }
      // cout<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<" "<<w<<endl;
      chkmin(ans, w + S(x1, y1, px, py));
      chkmin(ans, w + S(px, py, x2, y2));
      chkmin(ans, w + S(px, y1, x2, py));
      chkmin(ans, w + S(x1, py, px, y2));
    }
  }
  printf("%d\\n", ans);
  return 0;
}

Error: TLE

Fixed submission:

#include <stdio.h>
#define inf 9999998
#define GC getchar()
#define g(a, b, c, d) g[a][b][c][d]
using namespace std;
inline void min(int &a, int b) { a = a < b ? a : b; }
int n, m, f[45][45][45][45], xx, yy, sum[45][45], g[45][45][45][45];
bool mk[45][45][45][45];
char mp[45][45];
// inline int g(int xa,int ya,int xb,int yb){
//	return sum[xb][yb]-sum[xb][ya-1]-sum[xa-1][yb]+sum[xa-1][ya-1];
// }
inline bool is(int xa, int ya, int xb, int yb) {
  if (xa > xx || xb < xx || ya > yy || yb < yy)
    return 0;
  return 1;
}
void dfs(int xa, int ya, int xb, int yb) {
  // if(mk[xa][ya][xb][yb])return;
  // if(!mk[xa][ya][xb][yb])mk[xa][ya][xb][yb]=1;
  for (int i = xa; i < xb; i++) {
    for (int j = ya; j < yb; j++) {
      // if(g(xa,j+1,i,yb)>0||g(i+1,ya,xb,j)>0)continue;
      if (is(xa, ya, i, j)) {
        dfs(xa, ya, i, j);
        min(f[xa][ya][i][j],
            f[xa][ya][xb][yb] + g(xa, j + 1, i, yb) + g(i + 1, ya, xb, j));
      }
      if (is(i + 1, j + 1, xb, yb)) {
        dfs(i + 1, j + 1, xb, yb);
        min(f[i + 1][j + 1][xb][yb],
            f[xa][ya][xb][yb] + g(xa, j + 1, i, yb) + g(i + 1, ya, xb, j));
      }
      if (is(i + 1, ya, xb, j)) {
        dfs(i + 1, ya, xb, j);
        min(f[i + 1][ya][xb][j],
            f[xa][ya][xb][yb] + g(xa, ya, i, j) + g(i + 1, j + 1, xb, yb));
      }
      if (is(xa, j + 1, i, yb)) {
        dfs(xa, j + 1, i, yb);
        min(f[xa][j + 1][i][yb],
            f[xa][ya][xb][yb] + g(xa, ya, i, j) + g(i + 1, j + 1, xb, yb));
      }
    }
  } // printf("%d %d %d %d %d\\n",xa,ya,xb,yb,f[xa][ya][xb][yb]);
}
int main() {
  // freopen("haner3.in","r",stdin);
  // freopen("haner.out","w",stdout);
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      char ch = GC;
      while (ch != '+' && ch != '#' && ch != 'P')
        ch = GC;
      mp[j][i] = ch;
      if (ch == 'P')
        xx = j, yy = i;
    }
  }
  for (int i = 1; i <= m; i++) {
    for (int j = 1; j <= n; j++) {
      sum[i][j] =
          sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + (mp[i][j] == '#');
    }
  }
  for (int i = 1; i <= m; i++) {
    for (int j = 1; j <= n; j++) {
      for (int ii = i; ii <= m; ii++) {
        for (int jj = j; jj <= n; jj++) {
          f[i][j][ii][jj] = inf;
          g[i][j][ii][jj] =
              sum[ii][jj] - sum[ii][j - 1] - sum[i - 1][jj] + sum[i - 1][j - 1];
        }
      }
    }
  }
  f[1][1][m][n] = 0;
  dfs(1, 1, m, n);
  int ans = inf;
  for (int i = 1; i <= xx; i++) {
    for (int j = 1; j <= yy; j++) {
      for (int ii = xx; ii <= m; ii++) {
        for (int jj = yy; jj <= n; jj++) {
          min(ans, f[i][j][ii][jj] + g(i, j, xx, yy));
          min(ans, f[i][j][ii][jj] + g(xx, j, ii, yy));
          min(ans, f[i][j][ii][jj] + g(i, yy, xx, jj));
          min(ans, f[i][j][ii][jj] + g(xx, yy, ii, jj));
        }
      }
    }
  }
  printf("%d", ans);
}

/*
2 3
#H#
###
*/