忙完了學校的事,v神終於可以做他的「正事」:陪女朋友散步。一天,他和女朋友走著走著,不知不覺就來到了乙個千里無菸的地方。v神正要往回走,如發現了一塊牌子,牌子上有有一行小字和一張圖,小字說道:「找到圖上最大的交錯正方形之後和我聯絡,這塊地就是你的了。」在房價瘋長的年代,v神當然不願錯過這個機會,於是開始找了起來……以v神的能力當然找不出來了,你能幫v神找出來嗎?
圖上有乙個矩陣,由n*m個格仔組成,這些格仔由兩種顏色構成,黑色和白色。請找到面積最大的且內部是黑白交錯(即兩個相連的正方形顏色不能相同)的正方形。
第一行兩個整數n和m,分別表示行數和列數。接下來有n行,每行m個數,0或1分別表示這個格仔是黑色或白色。
僅有一行,表示滿足條件最大正方形的 邊長
輸入 #1複製
3 3輸出 #1複製0 1 0
1 0 0
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...