悬线法刷题记录
悬线法刷题记录
最近学习了悬线法,用极大化思想解决最大子矩阵问题,一种dp问题,留个记录……
讲的特别好的一个博客:极大化思想解决最大子矩阵问题
例题:
P1169 [ZJOI2007]棋盘制作
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 #define rep(x, l, r) for(int x = l; x <= r; x++) 7 #define repd(x, r, l) for(int x = r; x >= l; x--) 8 #define clr(x, y) memset(x, y, sizeof(x)) 9 #define all(x) x.begin(), x.end() 10 #define pb push_back 11 #define mp make_pair 12 #define MAXN 2005 13 #define fi first 14 #define se second 15 #define SZ(x) ((int)x.size()) 16 using namespace std; 17 typedef long long ll; 18 typedef vector<int> vi; 19 typedef pair<int, int> pii; 20 const int INF = 1 << 30; 21 const int p = 1000000009; 22 int lowbit(int x){ return x & (-x);} 23 int fast_power(int a, int b){ int x; for(x = 1; b; b >>= 1){ if(b & 1) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;} 24 25 int a[MAXN][MAXN], l[MAXN][MAXN], r[MAXN][MAXN], height[MAXN][MAXN]; 26 27 int main(){ 28 int n, m; 29 scanf("%d%d", &n, &m); 30 rep(i, 1, n) 31 rep(j, 1, m){ 32 scanf("%d", &a[i][j]); 33 height[i][j] = 1; 34 l[i][j] = r[i][j] = j; 35 } 36 rep(i, 1, n){ 37 rep(j, 2, m) 38 if(a[i][j] != a[i][j - 1]) l[i][j] = l[i][j - 1]; 39 } 40 rep(i, 1, n){ 41 repd(j, m - 1, 1) 42 if(a[i][j] != a[i][j + 1]) r[i][j] = r[i][j + 1]; 43 } 44 int ans1 = 0, ans2 = 0; 45 rep(i, 1, n){ 46 rep(j, 1, m){ 47 if(i != 1 && a[i - 1][j] != a[i][j]){ 48 height[i][j] = height[i - 1][j] + 1; 49 l[i][j] = max(l[i][j], l[i - 1][j]); 50 r[i][j] = min(r[i][j], r[i - 1][j]); 51 } 52 ans1 = max(ans1, min(height[i][j], r[i][j] - l[i][j] + 1) * min(height[i][j], r[i][j] - l[i][j] + 1)); 53 ans2 = max(ans2, height[i][j] * (r[i][j] - l[i][j] + 1)); 54 } 55 } 56 printf("%d\n%d\n", ans1, ans2); 57 return 0; 58 }
P4147 玉蟾宫
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 #define rep(x, l, r) for(int x = l; x <= r; x++) 7 #define repd(x, r, l) for(int x = r; x >= l; x--) 8 #define clr(x, y) memset(x, y, sizeof(x)) 9 #define all(x) x.begin(), x.end() 10 #define pb push_back 11 #define mp make_pair 12 #define MAXN 1005 13 #define fi first 14 #define se second 15 #define SZ(x) ((int)x.size()) 16 using namespace std; 17 typedef long long ll; 18 typedef vector<int> vi; 19 typedef pair<int, int> pii; 20 const int INF = 1 << 30; 21 const int p = 1000000009; 22 int lowbit(int x){ return x & (-x);} 23 int fast_power(int a, int b){ int x; for(x = 1; b; b >>= 1){ if(b & 1) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;} 24 25 int n, m; 26 int a[MAXN][MAXN], l[MAXN][MAXN], r[MAXN][MAXN], height[MAXN][MAXN]; 27 28 int main(){ 29 scanf("%d%d", &n, &m); 30 rep(i, 1, n) 31 rep(j, 1, m){ 32 char ch[5]; 33 scanf("%s", ch); 34 a[i][j] = ch[0] == 'F'; 35 l[i][j] = r[i][j] = j; 36 height[i][j] = 1; 37 } 38 rep(i, 1, n) 39 rep(j, 2, m) 40 if(a[i][j] && a[i][j - 1]) l[i][j] = l[i][j - 1]; 41 rep(i, 1, n) 42 repd(j, m - 1, 1) 43 if(a[i][j] && a[i][j + 1]) r[i][j] = r[i][j + 1]; 44 int ans = 0; 45 rep(i, 1, n) 46 rep(j, 1, m){ 47 if(!a[i][j]) continue; 48 if(i != 1 && a[i - 1][j]){ 49 l[i][j] = max(l[i][j], l[i - 1][j]); 50 r[i][j] = min(r[i][j], r[i - 1][j]); 51 height[i][j] = height[i - 1][j] + 1; 52 } 53 ans = max(ans, height[i][j] * (r[i][j] - l[i][j] + 1)); 54 } 55 printf("%d\n", 3 * ans); 56 return 0; 57 }
P2701 [USACO5.3]巨大的牛棚Big Barn
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 #define rep(x, l, r) for(int x = l; x <= r; x++) 7 #define repd(x, r, l) for(int x = r; x >= l; x--) 8 #define clr(x, y) memset(x, y, sizeof(x)) 9 #define all(x) x.begin(), x.end() 10 #define pb push_back 11 #define mp make_pair 12 #define MAXN 1005 13 #define fi first 14 #define se second 15 #define SZ(x) ((int)x.size()) 16 using namespace std; 17 typedef long long ll; 18 typedef vector<int> vi; 19 typedef pair<int, int> pii; 20 const int INF = 1 << 30; 21 const int p = 1000000009; 22 int lowbit(int x){ return x & (-x);} 23 int fast_power(int a, int b){ int x; for(x = 1; b; b >>= 1){ if(b & 1) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;} 24 25 int a[MAXN][MAXN], l[MAXN][MAXN], r[MAXN][MAXN], height[MAXN][MAXN]; 26 27 int main(){ 28 int n, m; 29 scanf("%d%d", &n, &m); 30 rep(i, 1, m){ 31 int x, y; 32 scanf("%d%d", &x, &y); 33 a[x][y] = 1; 34 } 35 rep(i, 1, n) 36 rep(j, 1, n){ 37 l[i][j] = r[i][j] = j; 38 height[i][j] = 1; 39 } 40 rep(i, 1, n) 41 rep(j, 2, n) 42 if(!a[i][j - 1] && !a[i][j]) l[i][j] = l[i][j - 1]; 43 rep(i, 1, n) 44 repd(j, n - 1, 1) 45 if(!a[i][j + 1] && !a[i][j]) r[i][j] = r[i][j + 1]; 46 int ans = 0; 47 rep(i, 1, n) 48 rep(j, 1, n){ 49 if(a[i][j]) continue; 50 if(i != 1 && !a[i - 1][j]){ 51 height[i][j] = height[i - 1][j] + 1; 52 l[i][j] = max(l[i][j], l[i - 1][j]); 53 r[i][j] = min(r[i][j], r[i - 1][j]); 54 } 55 ans = max(ans, min(height[i][j], r[i][j] - l[i][j] + 1)); 56 } 57 printf("%d\n", ans); 58 return 0; 59 }
P1387 最大正方形
代码如下
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 #define rep(x, l, r) for(int x = l; x <= r; x++) 7 #define repd(x, r, l) for(int x = r; x >= l; x--) 8 #define clr(x, y) memset(x, y, sizeof(x)) 9 #define all(x) x.begin(), x.end() 10 #define pb push_back 11 #define mp make_pair 12 #define MAXN 1005 13 #define fi first 14 #define se second 15 #define SZ(x) ((int)x.size()) 16 using namespace std; 17 typedef long long ll; 18 typedef vector<int> vi; 19 typedef pair<int, int> pii; 20 const int INF = 1 << 30; 21 const int p = 1000000009; 22 int lowbit(int x){ return x & (-x);} 23 int fast_power(int a, int b){ int x; for(x = 1; b; b >>= 1){ if(b & 1) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;} 24 25 int a[MAXN][MAXN], l[MAXN][MAXN], r[MAXN][MAXN], height[MAXN][MAXN]; 26 27 int main(){ 28 int n, m; 29 scanf("%d%d", &n, &m); 30 rep(i, 1, n) 31 rep(j, 1, m){ 32 scanf("%d", &a[i][j]); 33 l[i][j] = r[i][j] = j; 34 height[i][j] = 1; 35 } 36 rep(i, 1, n) 37 rep(j, 2, m) 38 if(a[i][j - 1] && a[i][j]) l[i][j] = l[i][j - 1]; 39 rep(i, 1, n) 40 repd(j, m - 1, 1) 41 if(a[i][j + 1] && a[i][j]) r[i][j] = r[i][j + 1]; 42 int ans = 0; 43 rep(i, 1, n) 44 rep(j, 1, m){ 45 if(!a[i][j]) continue; 46 if(i != 1 && a[i - 1][j]){ 47 height[i][j] = height[i - 1][j] + 1; 48 l[i][j] = max(l[i][j], l[i - 1][j]); 49 r[i][j] = min(r[i][j], r[i - 1][j]); 50 } 51 ans = max(ans, min(height[i][j], r[i][j] - l[i][j] + 1)); 52 } 53 printf("%d\n", ans); 54 return 0; 55 }