这道题目说是动态规划,但是感觉上更加靠近求最大矩形那个套路也就是hdu1506那道题目,有时间再刷吧,真的要考试了,不浪了,思路就是遇到一行中连续的1的时候,比如在第i行[s..e]区间中都是1,那么有是s<=k<=e,去在[s..k]区间中去寻找最大矩形,找到最大的矩形就是这一行的值,还是要学习一下hdu1506那道题目的思路,就是把那题的思路应用到每一行上来。最后再遍历一遍求出最优解就可以。
题目链接:https://vjudge.net/problem/HDU-1505
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1005;
int G[maxn][maxn];
int r,c;
int dp[maxn];
int check (int i , int s , int e) {
int up , down;
for (up = i ; up <= r ; up++) {
int flag = 1;
for (int j = s ; j <= e ; j++)
if (!G[up][j]) {flag = 0; break;}
if (!flag) break;
}
up--;
for (down = i ; down >= 1 ; down--) {
int flag = 1;
for (int j = s ; j <= e ; j++)
if (!G[down][j]) {flag = 0 ; break;}
if (!flag) break;
}
down++;
return up-down+1;
}
void solve () {
int res = 0;
for (int i = 1 ; i <= r ; i++) {
int ans = 0;
int s = 0 , e = 0;
int flag = 0;
for (int j = 1 ; j <= c ; j++) {
if (G[i][j] && !flag) {s = j; flag = 1; e = 0;}
if (!G[i][j] && flag) {
e = j;
flag = 0;
for (int k = s ; k <= e ; k++)
ans = max(ans , check(i,s,k)*(k-s+1));
}
}
if(s && !e)
for (int k = s ; k <= c ; k++)
ans = max(ans , check(i, s ,k)*(k-s+1));
dp[i] = ans;
}
for (int i = 1 ; i <= r ; i++)
res = max(res , dp[i]);
printf("%d\n" , res*3);
}
int main () {
int ncase;
scanf("%d" , &ncase);
while (ncase--) {
memset(G,0,sizeof(G));
scanf("%d%d" , &r , &c);
for (int i = 1 ; i <= r ; i++) {
for (int j = 1 ; j <= c ; j++) {
char tmp[2];
scanf("%s" , &tmp);
if (tmp[0] == 'F') G[i][j] = 1;
}
}
solve();
}
}