刚开始没想到怎么折状态转移
后来jfdalao给我讲了一遍才会
因为正方形的大小受到端点是否有鱼的限制
所以我们设s1(s2)i,j表示i,j左边(上面)最多有几个0
令f i,j表示以i,j为右下端点并且对角线经过i,j的对角线最大值
显然只有ai,j为1是才能转移
另外因为对角线有两个方向
所以我们应正反求两次
(代码是看别人的)
//P1736 创意吃鱼法 #include<bits/stdc++.h> using namespace std; int a[2505][2505],f[2505][2505],s1[2505][2505],s2[2505][2505]; int main(){ int n,m,ans=0; cin>>n>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&a[i][j]); if(!a[i][j]){ s1[i][j]=s1[i][j-1]+1; s2[i][j]=s2[i-1][j]+1; } if(a[i][j]) f[i][j]=min(f[i-1][j-1],min(s1[i][j-1],s2[i-1][j]))+1; ans=max(ans,f[i][j]); } } memset(f,0,sizeof(f)); memset(s1,0,sizeof(s1)); memset(s2,0,sizeof(s2)); for(int i=1;i<=n;i++){ for(int j=m;j>=1;j--){ if(!a[i][j]){ s1[i][j]=s1[i][j+1]+1; s2[i][j]=s2[i-1][j]+1; } if(a[i][j]) f[i][j]=min(f[i-1][j+1],min(s1[i][j+1],s2[i-1][j]))+1; ans=max(ans,f[i][j]); } } cout<<ans; return 0; }