aoj 動的計画法 最大正方形

DPL_3_A 最大正方形

DPL_3_A 最大正方形
Feb. 2, 2020, 1:52 p.m.

目次

問題

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_3_A

解説

タイルを表現する行列と同じサイズの行列をもう一つ用意する.
タイルを左上から順に見ていき、その時点での最大の辺の長さを以下のルールで記録していく.

1) 一番上か一番左のタイルなら、汚れていたら0、きれいなら1
2) その他のタイルで、自身が汚れていたら0
2) その他のタイルで、自身がきれいなら、自身の左、左上、上の3つの値のうち最小のものに1を加えた値

タイルを降るたびに最大値を更新していき、最終的な最大値が最大編の長さなので2乗すれば面積になる.

計算量

$O(N^2)$

解答

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#define MAX_N 1401

Int H, W;
bool S[MAX_N][MAX_N];
Int A[MAX_N][MAX_N];

void input() {
  cin >> H >> W;
  loop(h,0,H) {
    loop(w,0,W) {
      cin >> S[h][w];
      A[h][w] = -1;
    }
  }
}

void solve() {
  Int max_ = 0;
  loop(h,0,H) {
    A[h][0] = (S[h][0]) ? 0 : 1;
    max_ |= A[h][0];
  }
  loop(w,0,W) {
    A[0][w] = (S[0][w]) ? 0 : 1;
    max_ |= A[0][w];
  }

  loop(h,1,H) {
    loop(w,1,W) {
      if (S[h][w]) {
        A[h][w] = 0;
        continue;
      }

      A[h][w] = min(A[h-1][w], min(A[h][w-1], A[h-1][w-1])) + 1;
      if (A[h][w] > max_) max_ = A[h][w];
    }
  }

  cout << max_*max_ << endl;
}

int main(void) {
  input();
  solve();
}