72分求大佬相助!

P1736 创意吃鱼法

NewSjf @ 2019-09-13 11:13:28

RT
DP+前缀和的O(n^2)做法
f[i][j]代表以[i][j]为右下角的区域最大的子矩阵 g[i][j]代表以[i][j]为左下角的区域的最大子矩阵 从[i-1][j-1]或[i][j+1]转移过来,如果子矩阵周围全是0(对应前缀和差为0)
但是只有72分,4 5 10WA了
数据太大看不出什么端详
求大佬帮忙改错一下,谢谢了

#include<iostream>
#include<algorithm>
#define MAXN 2600
using namespace std;
bool a[MAXN][MAXN];
int n,m,f[MAXN][MAXN],g[MAXN][MAXN],ans;
int sumx[MAXN][MAXN],sumy[MAXN][MAXN];
bool check1(int x,int y)
{
    if(!a[x][y])return false;
    int t=f[x-1][y-1];
    if(x-t<1||sumx[x-1][y]-sumx[x-t-1][y])return false;
    if(y-t<1||sumy[x][y-1]-sumy[x][y-t-1])return false;
    return true;
}
bool check2(int x,int y)
{
    if(!a[x][y])return false;
    int t=g[x-1][y+1];
    if(x-t<1||sumx[x-1][y]-sumx[x-t-1][y]!=0)return false;
    if(y+t>m||sumy[x][y+t]-sumy[x][y]!=0)return false;
    return true;
} 
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            {
                cin>>a[i][j];
                f[i][j]=a[i][j];
                g[i][j]=a[i][j];
                sumx[i][j]=sumx[i-1][j]+a[i][j];
                sumy[i][j]=sumy[i][j-1]+a[i][j];
            }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(check1(i,j))f[i][j]=max(f[i][j],f[i-1][j-1]+1);
            if(check2(i,j))g[i][j]=max(g[i][j],g[i-1][j+1]+1);
            ans=max({ans,g[i][j],f[i][j]});
        }
    cout<<ans<<endl;
}
0 0 0 1
0 0 1 0 
0 1 0 1
1 0 0 0

by 18Michael @ 2022-03-03 20:49:12

@NewSjf 给组数据

4 4
1 0 0 1
0 0 1 0
0 1 0 1
1 0 0 0

输出是 3。


|