悬线法刷题记录

悬线法刷题记录

最近学习了悬线法,用极大化思想解决最大子矩阵问题,一种dp问题,留个记录……

讲的特别好的一个博客:极大化思想解决最大子矩阵问题

例题:

 

P1169 [ZJOI2007]棋盘制作

代码如下:

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 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 }
View Code

 

P4147 玉蟾宫

代码如下:

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 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 }
View Code

 

P2701 [USACO5.3]巨大的牛棚Big Barn

代码如下:

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 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 }
View Code

 

P1387 最大正方形

代码如下

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 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 }
View Code

你可能感兴趣的:(悬线法刷题记录)