暑期dp46道(39)--HDOJ 2870 最大子矩阵面积...
2016-08-18 16:59
459 查看
题目链接:HDOJ 2870
题意:给定一个仅由'a','b','c','w','x','y','z'组成的字符矩阵,且你可以把'w' 转成 (to)'a' 或 'b', 'x' to 'b' or 'c', 'y' to 'a' or 'c', 'z' to 'a', 'b' or 'c',求能转成的最大子矩阵面积;
题解:毫无疑问,对于'a','b','c'三种子矩阵,最大的时候一定是能转则转,总不能已经打算,所以分开考虑,每次转一种字符,求最大,然后求三个最大值的max,结束,这个矩阵求法,以前的博文里也有,那段时间 博客更新没有接上,直接补上 前面的链接:HDU 1505
题解 HDU 1506题解
此题代码:
#include<cstdio>
#include<cstring>
#include<string>
#define debug 0
#define M(a) memset(a,0,sizeof(a))
#define Max(a,b) ((a>b)?a:b)
const int maxn = 1000 + 5;
int l[maxn][maxn], r[maxn][maxn], h[maxn][maxn], data[maxn][maxn], ans;
int n, m;
int dir[][4] = { { 1,4,6,7 },{ 2,4,5,7 },{ 3,5,6,7 } };//用数组记录可转的字符情况
bool is(int a, int b)
{
for (int i = 0; i<4; i++)
{
if (dir[b - 1][i] == a)
return true;
}
return false;
}
void Do()
{
int temp, maxn;
for (int i = 1; i<4; i++)
{
maxn = 0;
M(l);
M(r);
M(h);
for (int j = 1; j <= n; j++)
{
for (int k = 1; k <= m; k++)
{
if (is(data[j][k], i))//判断当前的是否可转,和以前的矩阵是否为0是一样的
h[j][k] = h[j - 1][k] + 1;
else
h[j][k] = 0;
}
}
for (int j = 1; j <= n; j++)//求最大子矩阵面积
{
h[j][0] = h[j][m + 1] = -1;
for (int k = 1; k <= m; k++)
{
temp = k - 1;
while (h[j][temp] >= h[j][k])
{
temp = l[j][temp];
}
l[j][k] = temp;
}
for (int k = m; k >= 1; k--)
{
temp = k + 1;
while (h[j][temp] >= h[j][k])
{
temp = r[j][temp];
}
r[j][k] = temp;
}
for (int k = 1; k <= m; k++)
{
//printf("%d%d\n",r[j][k],l[j][k]);
maxn = Max(maxn, (r[j][k] - l[j][k] - 1)*h[j][k]);
}
}
ans = Max(ans, maxn);
}
printf("%d\n", ans);
}
int main()
{
#if debug
freopen("in.txt", "r", stdin);
#endif//debug
char a;
int temp;
while (~scanf("%d%d", &n, &m))
{
ans = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
while ((a = getchar()) == '\n' || a == ' ');
switch (a)//字符转为整数,用于数组记录
{
case 'a':temp = 1;
break;
case 'b':temp = 2;
break;
case 'c':temp = 3;
break;
case 'w':temp = 4;
break;
case 'x':temp = 5;
break;
case 'y':temp = 6;
break;
case 'z':temp = 7;
break;
default:break;
}
//putchar(a);
data[i][j] = temp;
}
}
Do();
}
return 0;
}
题意:给定一个仅由'a','b','c','w','x','y','z'组成的字符矩阵,且你可以把'w' 转成 (to)'a' 或 'b', 'x' to 'b' or 'c', 'y' to 'a' or 'c', 'z' to 'a', 'b' or 'c',求能转成的最大子矩阵面积;
题解:毫无疑问,对于'a','b','c'三种子矩阵,最大的时候一定是能转则转,总不能已经打算,所以分开考虑,每次转一种字符,求最大,然后求三个最大值的max,结束,这个矩阵求法,以前的博文里也有,那段时间 博客更新没有接上,直接补上 前面的链接:HDU 1505
题解 HDU 1506题解
此题代码:
#include<cstdio>
#include<cstring>
#include<string>
#define debug 0
#define M(a) memset(a,0,sizeof(a))
#define Max(a,b) ((a>b)?a:b)
const int maxn = 1000 + 5;
int l[maxn][maxn], r[maxn][maxn], h[maxn][maxn], data[maxn][maxn], ans;
int n, m;
int dir[][4] = { { 1,4,6,7 },{ 2,4,5,7 },{ 3,5,6,7 } };//用数组记录可转的字符情况
bool is(int a, int b)
{
for (int i = 0; i<4; i++)
{
if (dir[b - 1][i] == a)
return true;
}
return false;
}
void Do()
{
int temp, maxn;
for (int i = 1; i<4; i++)
{
maxn = 0;
M(l);
M(r);
M(h);
for (int j = 1; j <= n; j++)
{
for (int k = 1; k <= m; k++)
{
if (is(data[j][k], i))//判断当前的是否可转,和以前的矩阵是否为0是一样的
h[j][k] = h[j - 1][k] + 1;
else
h[j][k] = 0;
}
}
for (int j = 1; j <= n; j++)//求最大子矩阵面积
{
h[j][0] = h[j][m + 1] = -1;
for (int k = 1; k <= m; k++)
{
temp = k - 1;
while (h[j][temp] >= h[j][k])
{
temp = l[j][temp];
}
l[j][k] = temp;
}
for (int k = m; k >= 1; k--)
{
temp = k + 1;
while (h[j][temp] >= h[j][k])
{
temp = r[j][temp];
}
r[j][k] = temp;
}
for (int k = 1; k <= m; k++)
{
//printf("%d%d\n",r[j][k],l[j][k]);
maxn = Max(maxn, (r[j][k] - l[j][k] - 1)*h[j][k]);
}
}
ans = Max(ans, maxn);
}
printf("%d\n", ans);
}
int main()
{
#if debug
freopen("in.txt", "r", stdin);
#endif//debug
char a;
int temp;
while (~scanf("%d%d", &n, &m))
{
ans = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
while ((a = getchar()) == '\n' || a == ' ');
switch (a)//字符转为整数,用于数组记录
{
case 'a':temp = 1;
break;
case 'b':temp = 2;
break;
case 'c':temp = 3;
break;
case 'w':temp = 4;
break;
case 'x':temp = 5;
break;
case 'y':temp = 6;
break;
case 'z':temp = 7;
break;
default:break;
}
//putchar(a);
data[i][j] = temp;
}
}
Do();
}
return 0;
}
相关文章推荐
- 暑期dp46道(40)--HDOJ 2830 最大子矩阵面积 额
- HDU 1505 1506 2830 2870求最大矩阵面积 DP
- 暑期dp46道(31)--HDOJ 1087 最大上升子序列和 dp(水)
- 暑期dp46道(23)HDOJ 1059 Dividing 多重背包+二进制优化
- HDU-2870 Largest Submatrix (线性dp 最大01矩阵)(2009 Multi-University Training Contest 7 )
- 暑期dp46道(41)--HDOJ 1978 How many ways dfs + 记忆化搜索
- 九度OJ 1497:面积最大的全1子矩阵(DP)
- hdoj 1559 最大子矩阵 [dp]
- HDU 2870【DP_求最大矩阵】
- 【DP求最大子矩阵面积】hdu 1506
- hdoj 1559 最大子矩阵 【矩阵压缩 DP】
- 暑期dp46道(17)--HDOJ1114 Piggy Bank 完全背包
- Matrix Swapping II(求矩阵最大面积,dp)
- 暑期dp46道(28) hdoj 1502 Regular Words dp+高精度额
- 暑期dp46道(35)--HDOJ 2159 FATE 背包问题
- 暑期dp46道(43)--HDOJ 1159 最长公共子序列(可不连续)
- HDU 2870 Largest Submatrix(最大子矩阵面积)
- 暑期dp46道(9)——HDU 1505City Game 求最大子矩阵面积
- 暑期dp46道(12)--HDOJ 2191 多重背包+二进制优化
- 暑期dp46道(21)HDOJ 2059 龟兔赛跑