joj2325
据说要用dp,不过我用的是BFS,就是从上下左右四个方向压缩,在余下的面积不小于max的情况下一直到压缩出全为一的子阵,然后更新max的值,反复进行这个操作,即一开始的矩阵为:
1 1 1 1
0 0 0 0
1 1 1 1
0 0 0 0
可以压缩为:
0 0 0 0 (去掉第一行)
1 1 1 1
0 0 0 0
1 1 1 1 (去掉第四行)
0 0 0 0
1 1 1 1
1 1 1(去掉第一列)
0 0 0
1 1 1
0 0 0
1 1 1(去掉第四列)
0 0 0
1 1 1
0 0 0
然后反复压缩就可以了,一开始没考虑x1>x2和y1>y2的情况wa了好几次
#include<iostream>
#include<stdio.h>
#include<queue>
using namespace std;
int mm[32][32];
int dp[32][32][32][32];
struct node{
int x1;
int x2;
int y1;
int y2;
};
int rmax;
int check(node k)
{
int i,j;
for(i=k.y1;i<=k.y2;i++)
for(j=k.x1;j<=k.x2;j++)
{
if(mm[i][j]==0)
{
//if(k.y1==0&&k.y2==0&&k.x1==0&&k.x2==1)
//cout<<i<<" "<<j<<endl;
return 0;
}
}
return 1;
}
void bfs(int y1,int y2,int x1,int x2)
{
node k;
queue<node> q;
k.x1=x1;
k.y1=y1;
k.x2=x2;
k.y2=y2;
dp[y1][y2][x1][x2]=1;
q.push(k);
while(!q.empty())
{
node k;
k=q.front();
q.pop();
if(k.x1<0||k.x2<0||k.y1<0||k.y2<0)
continue;
if((k.y2-k.y1+1)*(k.x2-k.x1+1)<=rmax)
continue;
if(check(k))
rmax=(k.y2-k.y1+1)*(k.x2-k.x1+1);
node m;
if(k.x2-k.x1>0)
if(dp[k.y1][k.y2][k.x1+1][k.x2]==0)
{
m.x1=k.x1+1;
m.x2=k.x2;
m.y1=k.y1;
m.y2=k.y2;
dp[k.y1][k.y2][k.x1+1][k.x2]=1;
q.push(m);
}
if(k.x2>0&&k.x2-k.x1>0)
if(dp[k.y1][k.y2][k.x1][k.x2-1]==0)
{
m.x1=k.x1;
m.x2=k.x2-1;
m.y1=k.y1;
m.y2=k.y2;
dp[k.y1][k.y2][k.x1][k.x2-1]=1;
q.push(m);
}
if(k.y2>0&&k.y2-k.y1>0)
if(dp[k.y1][k.y2-1][k.x1][k.x2]==0)
{
m.x1=k.x1;
m.x2=k.x2;
m.y1=k.y1;
m.y2=k.y2-1;
dp[k.y1][k.y2-1][k.x1][k.x2]=1;
q.push(m);
}
if(k.y2-k.y1>0)
if(dp[k.y1+1][k.y2][k.x1][k.x2]==0)
{
m.x1=k.x1;
m.x2=k.x2;
m.y1=k.y1+1;
m.y2=k.y2;
dp[k.y1+1][k.y2][k.x1][k.x2]=1;
q.push(m);
}
//int ii,jj;
//for(ii=0;ii<3;ii++)
//{
// for(jj=0;jj<3;jj++)
// cout<<mm[ii][jj];
// cout<<endl;
//}
}
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int i,j,sum=0;
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
scanf("%d",&mm[i][j]);
if(mm[i][j]==1)
sum++;
}
if(sum==1||sum==0)
printf("%d\n",sum);
else
{
rmax=1;
bfs(0,n-1,0,m-1);
printf("%d\n",rmax);
}
}
}