USaco 6.1 A Rectangular Barn(最大サブマトリクス)
A Rectangular Barn Mircea Pasoi -- 2003
Ever the capitalist, Farmer John wants to extend his milking business by purchasing more cows. He needs space to build a new barn for the cows.
FJ purchased a rectangular field with R (1 ≤ R ≤ 3,000) rows numbered 1..R and C (1 ≤ C ≤ 3,000) columns numbered 1..C. Unfortunately, he realized too late that some 1x1 areas in the field are damaged, so he cannot build the barn on the entire RxC field.
FJ has counted P (0 ≤ P ≤ 30,000) damaged 1x1 pieces and has asked for your help to find the biggest rectangular barn (i.e., the largest area) that he can build on his land without building on the damaged pieces.
PROGRAM NAME: rectbarn
INPUT FORMAT
SAMPLE INPUT (file rectbarn.in)
3 4 2
1 3
2 1
OUTPUT FORMAT
SAMPLE OUTPUT (file rectbarn.out)
6
OUTPUT DETAILS
1 2 3 4
+-+-+-+-+
1| | |X| |
+-+-+-+-+
2|X|#|#|#|
+-+-+-+-+
3| |#|#|#|
+-+-+-+-+
Pieces marked with 'X' are damaged and pieces marked with '#' are part of the new barn.
题意:あなたに1つのn*mの行列をあげて、いくつかの格子は要らないで、最大のサブ行列の面积を求めます
解析:最大サブマトリクス問題は,点単位,次いで離散化再走査,複雑度O(P^2),格子単位走査,DPの2つの解法がある.複雑度はO(RC)で、データ量によって分析して、この問題は第2の方法を使うのに適しています.の具体的には王知昆の論文を見る
PS:この問題のデータは取れないですね.大きすぎるようですね.
コード:
/*
ID: 15114582
PROG: rectbarn
LANG: C++
*/
#include<cstdio>
#include<iostream>
using namespace std;
const int mm=3003;
int L[mm],H[mm],R[mm];
bool g[mm][mm];
int i,j,k,lm,rm,n,m,ans;
int main()
{
freopen("rectbarn.in","r",stdin);
freopen("rectbarn.out","w",stdout);
while(~scanf("%d%d%d",&n,&m,&k))
{
for(i=0;i<=n;++i)
for(j=0;j<=m;++j)
g[i][j]=1;
while(k--)
{
scanf("%d%d",&i,&j);
g[i][j]=0;
}
for(ans=j=0;j<=m;++j)H[j]=0,L[j]=1,R[j]=m;
for(i=1;i<=n;++i)
{
for(lm=j=1;j<=m;++j)
if(g[i][j])++H[j],L[j]=max(L[j],lm);
else H[j]=0,L[j]=1,R[j]=m,lm=j+1;
for(rm=j=m;j>=1;--j)
if(g[i][j])
{
R[j]=min(R[j],rm);
ans=max(ans,(R[j]-L[j]+1)*H[j]);
}
else rm=j-1;
}
printf("%d
",ans);
}
return 0;
}