BZOJ 1910: [Ctsc2002] Award 頒獎典禮
阿新 • • 發佈:2018-11-15
分成三個矩形 f[0..2][i][l][r] dp即可。
#include<bits/stdc++.h>
#define me(a,x) memset(a,x,sizeof a)
using namespace std;
const int N=202,inf=1e9+7;
char O[1<<14],*S=O,*T=O;
#define gc (S==T&&(T=(S=O)+fread(O,1,1<<14,stdin),S==T)?-1:*S++)
inline int read(){
int x=0,f=1; char ch=gc;
while (ch<'0' || ch>'9'){if(ch=='-')f=-1; ch=gc;}
while(ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+(ch^48); ch=gc;}
return x*f;
}
bool a[N][N];
int f[2][3][N][N],mx[N];
int main(){
int n=read(),m=read(),t,i,j,l,r;
for(i=1;i<=n;++i) for(j=1;j<=m;++j) a[i][j]=read();
me(f,-63 ); int u=0,ans=0;
for(i=1;i<=n;++i,u^=1){
me(f[u],-63);
for(l=1;l<=m;++l) for(r=l;r<=m && !a[i][r];++r)
f[u][0][l][r]=max(f[u^1][0][l][r],0)+r-l+1;
me(mx,-63);
for(l=2;l<m;++l){
for(j=m;j>l;--j)mx[j]=max(max(mx[j],mx[j+1]),f[u^1 ][0][l-1][j]);
for(r=l;r<m && !a[i][r];++r)
f[u][1][l][r]=max(f[u^1][1][l][r],mx[r+1])+r-l+1;
}
me(mx,-63);
for(l=m-2;l;--l){
for(j=l+1;j<m;++j)mx[j]=max(max(mx[j],mx[j-1]),f[u^1][1][l+1][j]);
for(r=l;r<=m && !a[i][r];++r)
f[u][2][l][r]=max(f[u^1][2][l][r],mx[r-1])+r-l+1,
ans=max(ans,f[u][2][l][r]);
}
}
printf("%d\n",ans);
return 0;
}