写了个最朴素的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;
}