HDU 4328 Cut the cake(最大子矩阵+悬线法)

来源:互联网 发布:淘宝联盟是干什么的 编辑:程序博客网 时间:2024/06/01 07:59


题意:给定一个n*m的棋盘有红黑两色,让截取一个周长最大矩形,该矩形要么全是黑色,要么全是红色,要么黑色和红色交替。

思路:UVALive 3029 的强化版,多了一种01交替的情况,方法也很简单,把(i+j)为奇数的格子颜色翻转然后再求两次即可。

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<vector>#include<map>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<ctime>#define eps 1e-6#define LL long long#define pii pair<int, int>//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const int MAXN = 1100;//const int INF = 0x3f3f3f3f;int m, n;int G[MAXN][MAXN], up[MAXN][MAXN], lef[MAXN][MAXN], rig[MAXN][MAXN];int solve(int id) {int ans = 0;for(int i = 1; i <= n; i++) rig[0][i] = n;for(int i = 1; i <= m; i++) {int leftmost = 1, rightmost = n;for(int j = 1; j <= n; j++) {if(G[i][j] != id) {leftmost = j + 1;lef[i][j] = up[i][j] = 0;}else {up[i][j] = up[i-1][j] + 1;lef[i][j] = max(leftmost, lef[i-1][j]);}}for(int j = n; j; j--) {if(G[i][j] != id) {rightmost = j - 1;rig[i][j] = n;}else rig[i][j] = min(rightmost, rig[i-1][j]);if(up[i][j]) ans = max(ans, (rig[i][j]-lef[i][j]+1)+up[i][j]);//cout << up[i][j] << " " << lef[i][j] << " " << rig[i][j] << endl;}}return ans * 2;}int main() {    //freopen("input.txt", "r", stdin);int T; cin >> T;int kase = 0;while(T--) {cin >> m >> n;char tmp[MAXN];for(int i = 1; i <= m; i++) {scanf("%s", tmp);for(int j = 1; j <= n; j++) G[i][j] = tmp[j-1]=='B' ? 1 : 0;}int ans = 0;ans = max(ans, solve(0));ans = max(ans, solve(1));for(int i = 1; i <= m; i++) {for(int j = 1; j <= n; j++) if((i+j)&1) G[i][j] ^= 1;}ans = max(ans, solve(0));ans = max(ans, solve(1));printf("Case #%d: %d\n", ++kase, ans);}    return 0;}


0 0
原创粉丝点击