233
dp[i][j]表示以i,j为右下角,能吃多少鱼。
这个可以从左上和右上推过来。
一个位置的符合条件的子矩阵就是统计左面有多少连续的0,上面有多少连续的0,取min即为答案。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[2600][2600];
int main()
{
int n,m;
//scanf("%d%d",&n,&m);
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(dp,0,sizeof dp);
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
scanf("%d",&dp[i][j]);
for(int j=1,tmp;j<=m;j++)
if(dp[i][j]==1)
{
tmp=dp[i-1][j-1];//左上
int l1,u1;
for(l1=1;l1<=tmp;l1++)
if(dp[i][j-l1]) break;
for(u1=1;u1<=tmp&&u1<=l1;u1++)
if(dp[i-u1][j]) break;
dp[i][j]=max(dp[i][j],min(l1,u1));
tmp=dp[i-1][j+1];//右上
int r2,u2;
for(r2=1;r2<=tmp;r2++)
if(dp[i][j+r2]) break;
for(u2=1;u2<=tmp&&u2<=r2;u2++)
if(dp[i-u2][j]) break;
dp[i][j]=max(dp[i][j],min(r2,u2));
ans=max(ans,dp[i][j]);
}
}
printf("%d",ans);
}
}