您的位置:首页 > 其它

bzoj 1768: [Ceoi2009]logs

2014-10-18 21:39 190 查看

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

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: