懸線法DP總結

2022-05-20 23:09:52 字數 2535 閱讀 7054

求滿足某種條件(如01交替)的最大矩形(正方形)

先預處理出\(ml[i][j],mr[i][j],mt[i][j]\),分別表示當前位置\((i,j)\)能向左擴充套件到的最左邊的編號、能向右擴充套件到的最右邊的編號、能向上擴充套件到的最大高度。

然後在做\(dp\)時,除第一行,每行根據上一行的狀態更新當前狀態,逐行掃一遍。複雜度\(o(n\times m)\)

洛谷題面

題意:求最大正方形

#include #define maxn 1010

#define max(a,b) ((a)>(b)?(a):(b))

#define min(a,b) ((a)<(b)?(a):(b))

using namespace std;

int n,t,ans;

bool mp[maxn][maxn];

int ml[maxn][maxn],mr[maxn][maxn],mt[maxn][maxn];

int main()

for(register int i=1;i<=n;++i)

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

for(register int j=2;j<=n;++j)

if(mp[i][j-1]==0&&mp[i][j]==0)

ml[i][j]=ml[i][j-1]; // 預處理出能向左擴充套件到的最左邊的編號

for(register int i=1;i<=n;++i)

for(register int j=n-1;j>=1;--j)

if(mp[i][j+1]==0&&mp[i][j]==0)

mr[i][j]=mr[i][j+1]; // 預處理出能向右擴充套件到的最右邊的編號

for(register int i=1;i<=n;++i)

for(register int j=2;j<=n;++j)

int w=min(mr[i][j]-ml[i][j]+1, mt[i][j]); // 因為是正方形

ans=max(ans, w);

}printf("%d", ans);

return 0;

}

p1169 洛谷題面

題意:求最大01交替正方形、長方形

#include #define maxn 2002

#define inf 0x3fffffff

#define max(a,b) ((a)>(b)?(a):(b))

#define min(a,b) ((a)<(b)?(a):(b))

using namespace std;

int n,m,ml[maxn][maxn],mr[maxn][maxn],mt[maxn][maxn];

int ans1, ans2;

bool mp[maxn][maxn];

int main()

int w = mr[i][j] - ml[i][j]+1;

int h = mt[i][j];

ans1 = max(min(w,h)*min(w,h), ans1); // 找出最大合法正方形

ans2 = max(w*h, ans2); // 找出最大合法矩形

}printf("%d\n%d", ans1, ans2);

return 0;

}

p4147 玉蟾宮

題意:毒瘤輸入,求最大正方形

#include #define maxn 1010

#define max(a,b) ((a)>(b)?(a):(b))

#define min(a,b) ((a)<(b)?(a):(b))

using namespace std;

int n,m,ans;

bool mp[maxn][maxn];

int ml[maxn][maxn],mr[maxn][maxn],mt[maxn][maxn];

int read()

int main()

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

for(register int j=2;j<=m;++j)

if(mp[i][j-1]==1&&mp[i][j]==1)

ml[i][j]=ml[i][j-1];

for(register int i=1;i<=n;++i)

for(register int j=m-1;j>=1;--j)

if(mp[i][j+1]==1&&mp[i][j]==1)

mr[i][j]=mr[i][j+1];

for(register int i=1;i<=n;++i)

for(register int j=2;j<=m;++j)

int w=mr[i][j]-ml[i][j]+1;

ans=max(ans, w*mt[i][j]);

}printf("%d", 3*ans);

return 0;

}

DP小技巧 懸線法

本來以為之前寫過這個方法,今天又考了一道模板題,於是就記錄一下 懸線法是求解一類極大子矩陣問題的dp解法 maybe 考試有人想出了 o n 2log 2n 的二分套二分做法,在此表示膜拜 即二分面積,列舉面積的約數 從暴力方面想,對於乙個點,直接求出它向左右上的最遠距離再乘起來可能不對,所以只能求...

ACM 懸線法總結

一般分為兩種做法 有乙個n m的矩陣,初始為白色,裡面有s個黑色格仔,現在問能在矩陣裡面找到的最大不包含 黑色格仔的子矩陣 正方形 n,m 1000,s n m 例題 p2701 usaco5.3 巨大的牛棚big barn 農夫約翰想要在他的正方形農場上建造一座正方形大牛棚。他討厭在他的農場中砍樹...

懸線法 有套路的DP

例題 p1169 zjoi2007 棋盤製作 西洋棋是世界上最古老的博弈遊戲之一,和中國的圍棋 象棋以及日本的將棋同享盛名。據說西洋棋起源於易經的思想,棋盤是乙個8 88 times 88 8大小的黑白相間的方陣,對應八八六十四卦,黑白對應陰陽。而我們的主人公小q,正是西洋棋的狂熱愛好者。作為乙個頂...