洛谷 P1681 最大正方形II 線性dp

2021-09-26 09:10:48 字數 2508 閱讀 1890

忙完了學校的事,v神終於可以做他的「正事」:陪女朋友散步。一天,他和女朋友走著走著,不知不覺就來到了乙個千里無菸的地方。v神正要往回走,如發現了一塊牌子,牌子上有有一行小字和一張圖,小字說道:「找到圖上最大的交錯正方形之後和我聯絡,這塊地就是你的了。」在房價瘋長的年代,v神當然不願錯過這個機會,於是開始找了起來……以v神的能力當然找不出來了,你能幫v神找出來嗎?

圖上有乙個矩陣,由n*m個格仔組成,這些格仔由兩種顏色構成,黑色和白色。請找到面積最大的且內部是黑白交錯(即兩個相連的正方形顏色不能相同)的正方形。

第一行兩個整數n和m,分別表示行數和列數。接下來有n行,每行m個數,0或1分別表示這個格仔是黑色或白色。

僅有一行,表示滿足條件最大正方形的 邊長

輸入 #1複製

3 3

0 1 0

1 0 0

1 1 1

輸出 #1複製

2
樣例解釋:

(1,1)到(2,2)這個正方形是滿足條件的,它的邊長是2

資料範圍約定:

對於30%的資料,n <= 20

對於60%的資料,n <=300

對於100%的資料,n <= 1500

其實是最大正方形的變形。

正方形那題是令dp[i][j]是以(i,j)為右下角能得到的最大正方形邊長,而這次只要加乙個維度判斷黑白格就行了。。

令dp[i][j][0/1]是以(i,j)為右下角,且該點上為0/1時能得到的最大正方形邊長,則:

1.當a[i][j]=0時

dp[i][j][0]=min(dp[i-1][j][1],dp[i][j-1][1],dp[i-1][j-1][0])+1

2.當a[i][j]=1時

dp[i][j][1]=min(dp[i-1][j][0],dp[i][j-1][0],dp[i-1][j-1][1])+1

這裡來著重講一下為什麼狀態轉移方程中為什麼要取min而不是取max。

你想啊,點(i,j)可以從(i-1,j)轉移過來,也可以從(i,j-1)轉移過來,也可以從(i-1,j-1)轉移過來。這3個點要同時兼顧,而(i,j)是決定存在性問題的,如果我取max,我這邊可能滿足條件,但就不保證其他兩邊滿足條件了。如果你不能理解,我們舉個例子就明白了:

假如有乙個a陣列a[4][4]:

1 0 1 0

0 1 0 1

1 0 1 0

0 1 0 0

則dp陣列:(這裡dp陣列用2維表示,為了舉例方便)

1 0 0 0

0 0 0 0

0 0 0 0

0 0 0 0

1 1 1 1

1 0 0 0

0 0 0 0

0 0 0 0

在dp[2][2]中,顯然可以從dp[1][2],dp[2][1],dp[1][1]這3個點轉移,看一下a陣列:

1 0

0 1

是可以轉移的,於是dp陣列

1 1

1 2

dp陣列

1 1 1 1

1 2 2 2

1 2 2 2

1 2 2 0

等等,dp[3][3]應該為3啊!

好。

1 1 1 1

1 2 2 2

1 2 3 2

1 2 2 0

那麼我們接著看dp[4][3],發現dp[4][2]=2,dp[3][3]=3,dp[3][2]=2,周圍有2個2,1個3,選哪個呢?

好,按照我們之前的慣性思維,如果取max的話,也就是選dp[3][3]的話,則dp陣列:

1 1 1 1

1 2 2 2

1 2 3 2

1 2 4 0

發現它並不能構成邊長為4的正方形!所以要選邊長為2的。

最後dp陣列:

1 1 1 1

1 2 2 2

1 2 3 3

1 2 3 0

也就是說,dp[i][j]的選擇,是要兼顧dp[i-1][j],dp[i][j-1],dp[i-1][j-1]的最小值的。如果取最大值的話,顯然不能保證dp[i][j]是否還能正確。取最小值是為了能保證dp[i][j]也能滿足條件,隨著i和j的增大,dp[i][j]一定能保證單調遞增的。

#include #include #define inf 2e9+7

using namespace std;

int dp[1501][1501][2],a[1501][1501],n,m,s;

signed main()

} for(i=1;i<=n;i++)

if(a[i][j]==1)

}} cout

}

洛谷P1681 最大正方形II

忙完了學校的事,v神終於可以做他的 正事 陪女朋友散步。一天,他和女朋友走著走著,不知不覺就來到 了乙個千里無菸的地方。v神正要往回走,如發現了一塊牌子,牌子上有有一行小字和一張圖,小字說道 找到圖上最大的交錯正方形之後和我聯絡,這塊地就是 你的了。在房價瘋長的年代,v神當然不願錯過這個機會,於是開...

P1681 最大正方形 Iand II

在乙個n m的只包含0和1的矩陣裡找出乙個不包含0的最大正方形,輸出邊長。輸入格式 輸入檔案第一行為兩個整數n,m 1 n,m 100 接下來n行,每行m個數字,用空格隔開,0或1.輸出格式 乙個整數,最大正方形的邊長 輸入樣例 1 複製4 4 0 1 1 1 1 1 1 0 0 1 1 0 1 1...

luogu P1681 最大正方形II

交了十幾遍才過,本來這只是一道水題,然而誰讓我快讀寫炸了呢 詳情見 gg記錄 6 f i j 表示i,j位置為右下角的最大正方形 如果i或j為1,很顯然,f i j 的值最大為1,否則便要從三個方向取最小值轉移 如果不滿足轉移的條件,將其賦值為1即可 includevoid read int y i...