SSL1317 本来以为暴力枚举矩形左上角dfs推右下角的点和DP复杂度一样结果一想发现复杂度整整多了个n = =
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<bitset> #define LL long long #define fo(i,a,b) for(int i=a;i<=b;i++) #define down(i,a,b) for(int i=a;i>=b;i--) using namespace std; inline LL read() { LL d=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();} return d*f; } #define N 55 #define NM 64 unsigned long a[N][N],f[N][N],ff[N][N]; int pre[5][3]; int n,m,nm,ans=10000; void floodfill(int x,int y,int color) { if(a[x][y]==0)return; if(f[x][y]==color)return; f[x][y]=color; fo(i,1,4) floodfill(x+pre[i][1],y+pre[i][2],color); } void prework() { memset(a,0,sizeof(a)); memset(f,0,sizeof(f)); n=read(),m=read(); fo(i,1,n) { fo(j,1,m) { a[i][j]=read()^1; } } int cnt=1; fo(i,-1,1) fo(j,-1,1) if(abs(i+j)==1) pre[cnt][1]=i,pre[cnt++][2]=j; cnt=0; fo(i,1,n) fo(j,1,m) if(a[i][j]==1&&f[i][j]==0)floodfill(i,j,++cnt); nm=cnt; } void DP() { fo(i,1,n) fo(j,1,m) { memset(ff,0,sizeof(ff)); fo(p,i,n) fo(q,j,m) { ff[p][q]=ff[p-1][q]|ff[p][q-1]; if(f[p][q]&&!(ff[p][q]&(1<<(f[p][q]-1)))) ff[p][q]+=1<<(f[p][q]-1); if(ff[p][q]==(1<<nm)-1)ans=min(ans,(p-i+1)*(q-j+1)); } } } int main() { prework(); DP(); cout<<ans<<endl; return 0; }