写了个最朴素的dfs
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int a[10][10],sum[10],ans; int n,m,k; int quex[111],quey[111],front,end; bool chk(int t,int s,int use[10][10]) { int ret=0; int x,y; front=1,end=0; quex[++end]=t; quey[end]=s; while(front<=end) { x=quex[front]; y=quey[front++]; for(int i=-1;i<=1;i++) for(int j=-1;j<=1;j++) if(!use[x+i][y+j]&&a[x+i][y+j]==a[t][s]) { use[x+i][y+j]=t*m+s; ret++; quex[++end]=x+i; quey[end]=y+j; } } return ret>=3; } void prin() { for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) printf("%d ",a[i][j]); puts(""); } puts(""); } int work(int t,int s,int use[10][10]) { int ret=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(use[i][j]==use[t][s]) { a[i][j]=0; ret++; } // prin(); for(int i=1,t;i<=m;i++) { t=n+1; for(int j=n;j>=1;j--) if(a[j][i]) { a[--t][i]=a[j][i]; if(t!=j) a[j][i]=0; } } // prin(); for(int i=1,t=0;i<=m;i++) { bool flag=false; for(int j=1;j<=n;j++) if(a[j][i]) { flag=true; break; } if(flag&&++t!=i) { for(int j=1;j<=n;j++) { a[j][t]=a[j][i]; a[j][i]=0; } } } // prin(); return ret; } inline void mov(int a[10][10],int b[10][10]) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=b[i][j]; } int cal() { int ret=0; for(int i=1;i<=k;i++) if(sum[i]>=3) ret+=sum[i]*sum[i]; return ret; } void dfs(int ret) { if(ret+cal()<=ans) { return ; } int now[10][10]; int use[10][10]; int txt; ans=max(ans,ret); memset(use,0,sizeof(use)); for(int i=1,tmp;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]&&!use[i][j]&&chk(i,j,use)) { txt=a[i][j]; mov(now,a); tmp=work(i,j,use); sum[txt]-=tmp; dfs(ret+tmp*tmp); sum[txt]+=tmp; mov(a,now); } } int main() { // freopen("in.txt","r",stdin); while(scanf("%d%d%d",&n,&m,&k)!=EOF) { memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&a[i][j]); sum[a[i][j]]++; } ans=0; dfs(0); cout<<ans<<endl; } return 0; }