Przechodzę przez kilka rozwiązań zwiększających trudności/zmniejszających złożoność środowiska wykonawczego.
Po pierwsze, rozwiązanie brutalnej siły. Wygeneruj każdy możliwy prostokąt. Możesz to zrobić przez powtarzanie każdej pary punktów (r1, c1) (r2, c2) z r1 ≤ r2 i c1 ≤ c2 (można zrobić z 4 dla pętli). Jeśli prostokąt nie zawiera wartości 0, porównujesz obszar do największego znalezionego do tej pory obszaru. To jest O (R^3C^3).
Możemy przyspieszyć prawidłowe sprawdzanie prostokąta do O (1). Robimy to, wykonując DP, w którym dp (r, c) przechowuje liczbę 0 w prostokącie ((1, 1), (r, c)).
- DP (r, 0) = 0
- DP (0 C) = 0
- DP (R c) DP = (R-1 c) + DP (R, C 1) -dp (r-1, c-1) + (macierz [r] [c] 0: 1)
Następnie liczba 0 w ((r1, c1), (r2, c2)) jest
- nzeroes (R1, C1, R2, C2) = Dp [r2] [C2] -DP [r1 -1], [C2] -DP [R2] [C1 -1] + [DP r1 -1] [c1 -1]
Następnie można sprawdzić, czy prostokąt jest ważny przez nozniki (r1, c1, r2, c2) == 0.
Istnieje rozwiązanie O (R^2C) do tego przy użyciu prostego DP i stosu. DP działa na kolumnę, znajdując liczbę 1 komórek powyżej komórki do następnego 0. Wartość dp jest następująca:
dp (r, 0) = 0 dp (r, c) = 0, jeśli macierz [R], [c] == 0 DP (R c) (R = DP-1, c) + 1 poza
wtedy należy wykonać następujące czynności:
area = 0
for each row r:
stack = {}
stack.push((height=0, column=0))
for each column c:
height = dp(r, c)
c1 = c
while stack.top.height > height:
c1 = stack.top.column
stack.pop()
if stack.top.height != height:
stack.push((height=height, column=c1))
for item in stack:
a = (c - item.column + 1) * item.height
area = max(area, a)
jest również możliwe, aby rozwiązać problem w O (RC) za pomocą trzech DP:
- h (r, c): jeśli zaczniemy od (r, c) i pójdziemy w górę, ile 1 komórek znajdziemy przed pierwszymi 0?
- l (r, c): jak daleko możemy rozciągnąć prostokąt z dolnym prawym rogiem na (r, c) i wysokości h (r, c)?
- r (r, c): jak daleko na prawo możemy rozciągnąć prostokąt z dolnym lewym rogiem na (r, c) i wysokości h (r, c)?
Trzy stosunki nawrotów:
- H 0 (c) = 0
- H (R, C) = 0, jeżeli macierz [R], [c] == 0
h (R, C) = h (r-1 C) +1 inaczej
l (r, 0) = 0
- l (R, C) = CP jeśli matryca [r- 1] [c] == 0
l (R, C) = min (l (R - 1, c), c - p) poza
R (R, C + 1) = 0
- R (r, c) = pc, jeśli matryca [r-1], [c] == 0
- R (R, C) = min (R (R - 1, c), PC) poza
gdzie p jest kolumną poprzedniego 0, gdy wypełniamy l od lewej do prawej i r od prawej do lewej.
Odpowiedź wynosi:
- max_r C (H (r, c) * (l (R c) + R (R c) - 1))
Działa to z powodu obserwacji, że największy prostokąt zawsze dotyka 0 (biorąc pod uwagę krawędź jako pokryty w 0) na wszystkich czterech bokach. Rozważając wszystkie prostokąty z co najmniej górną, lewą i prawą powierzchnią dotykając 0, pokrywamy wszystkie kandydujące prostokąty. Wygeneruj każdy możliwy prostokąt. Możesz to zrobić przez powtarzanie każdej pary punktów (r1, c1) (r2, c2) z r1 ≤ r2 i c1 ≤ c2 (można zrobić z 4 dla pętli). Jeśli prostokąt nie zawiera wartości 0, porównujesz obszar do największego znalezionego do tej pory obszaru.
Uwaga: dostosowałem powyższą odpowiedź z odpowiedzi, którą napisałem: here - patrz rozdział "Mama Bena". W tym zapisie 0 to drzewa. Ten zapis ma również lepsze formatowanie.
thanx za tak dobre rozwiązanie. – RATHI
Dziękuję bardzo. Świetne rozwiązania. –