您的位置:首页 > 其它

hdu 2870 Largest Submatrix (dp)

2014-06-04 12:09 399 查看
小记:这个算是1506,1505的再次升级版吧,1506是一维版本,1505是二维版本,这个2870则是可以变动两三次的二维版本。 1A!

思路:如1505一样,我们一行一行的处理, 因为w,x,y,z都可以变,但是a,b,c不能变,那么我们以a,b,c为基础,每个w,x,y,z都变a,或b或c。

即,我们对每一个点计算出它是a或者b或者c时所能得到的最大子矩

h[i][j] 表示当前行第i个字符是j 然后往上碰到第一个不同的字符的高度

l[i][j] 表示当前行第i个字符是j的时候,其左边连续到它这个位置高度大于等于它自己的高度的最长长度

r[i][j] 表示当前行第i个字符是j的时候,其右边连续到它这个位置高度大于等于它自己的高度的最长长度

因为a,b,c不变,所以j 的值只有3个,我们对每个点处理下三个值所能得到的最大值,保存最大的那个就是结果了

if( 当前字符== j ) h[i][j] ++, 其它字符都归0

l[i][j] = l[l[i][j] - 1][j]   (l[i][j] > 0 && h[l[i][j] - 1] >= h[i][j]) (j = 1(a),2( b),3 (c))

r[i][j] = r[l[i][j] - 1][j]   (r[i][j] +1 > m && h[r[i][j] - 1] >= h[i][j])  (j = 1(a), 2(b), 3(c))

初始化 记得 l[i][j] = -1, r[i][j] = m,然后碰到j的时候 就左右都赋值为 i, 高度初始化都为0

code:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>

using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))
#define REP(a,b,c) for(int a = b; a < c; ++a)
#define eps 10e-8

const int MAX_ = 1010;
const int N = 100010;
const int INF = 0x7fffffff;

int h[MAX_][3];
int l[MAX_][3], r[MAX_][3];
char str[MAX_][MAX_];

int main(){
int n, m, ans;

while(~scanf("%d%d", &n, &m)){
REP(i, 0, m){
REP(ii, 0, 3){
l[i][ii] = -1;
r[i][ii] = m;
h[i][ii] = 0;
}
}
ans = -1;

REP(j, 0, n){
scanf("%s", str[j]);
REP(i, 0, m){
switch(str[j][i]){
case 'a': l[i][0] = i; r[i][0] = i; h[i][0]++; h[i][1] = 0; h[i][2] = 0;
break;
case 'b': l[i][1] = i; r[i][1] = i; h[i][0] = 0; h[i][1] ++; h[i][2] = 0;
break;
case 'c': l[i][2] = i; r[i][2] = i; h[i][0] = 0; h[i][1] = 0; h[i][2] ++;
break;
case 'w': l[i][0] = i; r[i][0] = i; l[i][1] = i; r[i][1] = i; h[i][0]++; h[i][1] ++; h[i][2] = 0;
break;
case 'x': l[i][1] = i; r[i][1] = i; l[i][2] = i; r[i][2] = i; h[i][0] = 0; h[i][1] ++; h[i][2] ++;
break;
case 'y': l[i][2] = i; r[i][2] = i; l[i][0] = i; r[i][0] = i; h[i][0]++; h[i][1] = 0; h[i][2] ++;
break;
case 'z': l[i][0] = i; r[i][0] = i; l[i][1] = i; r[i][1] = i; l[i][2] = i; r[i][2] = i; h[i][0] ++; h[i][1] ++; h[i][2] ++;
break;
}
}
REP(ii, 0, 3){
REP(k, 0, m){
while(l[k][ii] > 0 && h[l[k][ii] - 1][ii] >= h[k][ii]){
l[k][ii] = l[l[k][ii] - 1][ii];
}
}
}

REP(ii, 0, 3){
for(int k = m-1; k > -1; --k){
while(r[k][ii] + 1 < m && h[r[k][ii] + 1][ii] >= h[k][ii]){
r[k][ii] = r[r[k][ii] + 1][ii];
}
}
}

REP(ii, 0, 3){
REP(k, 0, m){
if(l[k][ii] < 0 || r[k][ii] > m-1)continue;
int tmp = (r[k][ii] - l[k][ii] + 1) * h[k][ii];
//printf(" | (%d %d) = %d | ", l[k][ii], r[k][ii], tmp);
ans = max(ans, tmp);
}
}
//printf("\n");
}
printf("%d\n", ans);
}
return 0;
}


l[i][j] = l[l[i][j] - 1][j]   (l[i][j] > 0 && h[l[i][j] - 1] >= h[i][j])
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: