Description
有一个N*M的01矩阵,现在你可以的任意交换其中的列,要求找一个最大的仅由1组成的矩阵。 N<=15000,M<=1500 1 ≤ N ≤ 15000 1 ≤ M ≤ 1500 30% of the test cases will have N,M ≤ 1024
Input
N,M 以下N行每行M个字符。
Output
Sample Input
10 6
001010
111110
011110
111110
011110
111111
110111
110111
000101
010101
001010
111110
011110
111110
011110
111111
110111
110111
000101
010101
Sample Output
21
HINT
By permuting the columns such that columns 2,
4 and 5 are adjacent you have a rectangle of area
21 (rows 2-8 and columns 2, 4, 5).
ceoi是中欧么...连题解都只有一篇还看不太懂
http://blog.sina.com.cn/s/blog_7cd3ac450100skzu.html
我们用f[i][j]表示该列最多向下延伸的长度。
若s[i][j]=0 则f[i][j]=0,否则f[i][j]=f[i-1][j]+1 【因为统一列的顺序不变】
然后用t[i]表示横向最多延伸的长度,q数组记录1的位置
然后因为内存只有64M所以要滚动数组
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
int i,j,n,ans,l,r,m;
string s;
int f[2][1501],q[2][1501];
bool d[2][1501];
int t[2];
int main()
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
l=i&1;
r=(i+1)&1;
t[l]=0;
cin>>s;
for(j=1;j<=m;j++)
{
if(s[j-1]=='1')
{
d[l][j]=true;
if(!d[r][j])
{
t[r]++;
q[r][t[r]]=j;
f[l][j]=1;
}
else
f[l][j]=f[r][j]+1;
}
else
{
d[l][j]=false;
f[l][j]=0;
}
}
for(j=1;j<=t[r];j++)
{
if(d[l][q[r][j]])
{
t[l]++;
q[l][t[l]]=q[r][j];
if(f[l][q[r][j]]*t[l]>ans)
ans=f[l][q[r][j]]*t[l];
}
}
}
printf("%d\n",ans);
return 0;
}