码迷,mamicode.com
首页 > 其他好文 > 详细

最大子矩阵问题&悬线法小结

时间:2020-03-26 12:26:17      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:制作   getchar   getc   悬线法   read   using   const   amp   print   

\(\large{例题1.}\) \(\large{\text{ZJOI}2007棋盘制作}\)
\(\\\)
\(\large{证明一下做法的正确性,首先如果一个矩形面积最大,那么它一定顶着边界。\\然后更新up、l、r当且仅当a[i][j] 与 a[i-1][j]满足一定的关系,对其余的up、l与r无影响,也就对最大矩阵无影响。}\)
\(\\\)
\(\Large\textbf{Code: }\)

#include <bits/stdc++.h>
#define gc() getchar() 
#define LL long long
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rep(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
const int N = 2e3 + 5;
int n, m, ans1, ans2, a[N][N], up[N][N], l[N][N], r[N][N];

inline int read() {
	int x = 0, flg = 1;
	char ch = gc();
	while (!isdigit(ch)) ch = gc();
	while (isdigit(ch)) x = x * 10 + ch - ‘0‘, ch = gc();
	return x * flg; 
}

int main() {
	n = read(), m = read();
	rep(i, 1, n) 
		rep(j, 1, m) {
			a[i][j] = read(); up[i][j] = 1;
			l[i][j] = r[i][j] = j;
			if (a[i][j] != a[i][j - 1] && j > 1) l[i][j] = l[i][j - 1];
		}
	rep(i, 1, n) _rep(j, m, 1) if (a[i][j] != a[i][j + 1] && j < m) r[i][j] = r[i][j + 1];
	rep(i, 1, n) 
		rep(j, 1, m) {
			if (i > 1 && a[i][j] != a[i - 1][j]) {
				l[i][j] = max(l[i][j], l[i - 1][j]);
				r[i][j] = min(r[i][j], r[i - 1][j]);
				up[i][j] = up[i - 1][j] + 1;
			}
			int a = r[i][j] - l[i][j] + 1, b = min(up[i][j], a);
			ans1 = max(ans1, b * b), ans2 = max(ans2, a * up[i][j]);
		}
	printf("%d\n%d\n", ans1, ans2);
	return 0;
} 

\(\large{例题2.}\) \(\large{玉蟾宫}\)
\(\\\)
\(\large{做法同上}\)
\(\\\)

#include <bits/stdc++.h>
#define gc() getchar() 
#define LL long long
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rep(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
const int N = 1e3 + 5;
int n, m, ans, up[N][N], l[N][N], r[N][N];
char a[N][N];

inline int read() {
	int x = 0, flg = 1;
	char ch = gc();
	while (!isdigit(ch)) ch = gc();
	while (isdigit(ch)) x = x * 10 + ch - ‘0‘, ch = gc();
	return x * flg; 
}

int main() {
	n = read(), m = read();
	rep(i, 1, n) 
		rep(j, 1, m) {
			cin >> a[i][j]; up[i][j] = 1;
			l[i][j] = r[i][j] = j;
			if (a[i][j] == a[i][j - 1] && a[i][j] == ‘F‘ && j > 1) l[i][j] = l[i][j - 1];
		}
	rep(i, 1, n) _rep(j, m, 1) if (a[i][j] == a[i][j + 1] && a[i][j] == ‘F‘ && j < m) r[i][j] = r[i][j + 1];
	rep(i, 1, n) 
		rep(j, 1, m) {
			if (i > 1 && a[i][j] == a[i - 1][j] && a[i][j] == ‘F‘) {
				l[i][j] = max(l[i][j], l[i - 1][j]);
				r[i][j] = min(r[i][j], r[i - 1][j]);
				up[i][j] = up[i - 1][j] + 1;
			}
			int a = r[i][j] - l[i][j] + 1;
			ans = max(ans, a * up[i][j]);
		}
	printf("%d\n", ans * 3);
	return 0;
} 

最大子矩阵问题&悬线法小结

标签:制作   getchar   getc   悬线法   read   using   const   amp   print   

原文地址:https://www.cnblogs.com/Miraclys/p/12572881.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!