题目大意
流行的跳棋游戏是在一个有m*n个方格的长方形棋盘上玩的。棋盘起初全部被动物或障碍物占满了。在一个方格中,‘X’表示一个障碍物,一个‘0’~‘9’的个位数字表示一个不同种类的动物,相同的个位数字表示相同种类的动物。一对动物只有当它们属于同一种类时才可以被消去。消去之后,他们所占的方格就成为空方格,直到游戏结束。要消去一对动物的前提条件是:这对候选动物所在的方格必须相邻,或它们之间存在一条通路。棋盘上一个方格只和其上下左右的方格相邻。一条通路是由一串相邻的空方格组成。路的长度则是通路中空方格的数目。你要输出可被消去的动物的最多对数,以及在此操作过程中,最小的通路长度总和。
解题思路
直接搜索,枚举删除一对可行的点,随便加点剪枝就可以了。
code
using namespace std;
int const inf=2147483647;
int const maxn=10000;
int n,m,ans1,ans2,cntt,q1[30][30],q2[30][30],cnt[30],dis[30][30],in[30][30][30],use[30][30],w[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
char map[100][100];
void dfs(int x,int y){
cntt++;
if(cntt>=400000)return;
if(x>ans1){ans1=x,ans2=y;}
else if((x==ans1)&&(y<ans2))ans2=y;
int head=0,tail=0,lim=inf;
fo(i,1,m)
fo(j,1,n)
if((!use[i][j])&&(cnt[map[i][j]]>1)){
head=0;q1[x][tail=1]=i;q2[x][tail]=j;dis[x][tail]=-1;
fo(ii,1,m)fo(jj,1,n)in[x][ii][jj]=0;in[x][i][j]=1;
for(;head!=tail;){
head++;
fo(k,0,3)
if(use[q1[x][head]+w[k][0]][q2[x][head]+w[k][1]]){
if((!in[x][q1[x][head]+w[k][0]][q2[x][head]+w[k][1]])&&(dis[x][head]+1<lim)){
q1[x][++tail]=q1[x][head]+w[k][0];
q2[x][tail]=q2[x][head]+w[k][1];
dis[x][tail]=dis[x][head]+1;
in[x][q1[x][head]+w[k][0]][q2[x][head]+w[k][1]]=1;
}
}else if((dis[x][head]+1<=lim)&&((i!=q1[x][head]+w[k][0])||(j!=q2[x][head]+w[k][1]))&&(map[q1[x][head]+w[k][0]][q2[x][head]+w[k][1]]==map[i][j])){
lim=dis[x][head]+1;
head=tail;
break;
}
}
}
if(lim==inf)return;
fo(i,1,m)
fo(j,1,n)
if((!use[i][j])&&(cnt[map[i][j]]>1)){
head=0;q1[x][tail=1]=i;q2[x][tail]=j;dis[x][tail]=-1;
fo(ii,1,m)fo(jj,1,n)in[x][ii][jj]=0;in[x][i][j]=1;
for(;head!=tail;){
head++;
fo(k,0,3)
if(use[q1[x][head]+w[k][0]][q2[x][head]+w[k][1]]){
if((!in[x][q1[x][head]+w[k][0]][q2[x][head]+w[k][1]])&&(dis[x][head]+1<=lim+2)){
q1[x][++tail]=q1[x][head]+w[k][0];
q2[x][tail]=q2[x][head]+w[k][1];
dis[x][tail]=dis[x][head]+1;
in[x][q1[x][head]+w[k][0]][q2[x][head]+w[k][1]]=1;
}
}else if((dis[x][head]+1<=lim+2)&&((i!=q1[x][head]+w[k][0])||(j!=q2[x][head]+w[k][1]))&&(map[q1[x][head]+w[k][0]][q2[x][head]+w[k][1]]==map[i][j])){
use[i][j]=use[q1[x][head]+w[k][0]][q2[x][head]+w[k][1]]=1;
cnt[map[i][j]]-=2;
dfs(x+1,y+dis[x][head]+1);
cnt[map[i][j]]+=2;
use[i][j]=use[q1[x][head]+w[k][0]][q2[x][head]+w[k][1]]=0;
}
}
}
}
int main(){
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
scanf("%d%d\n",&m,&n);
fo(i,1,m){
fo(j,1,n){
scanf("%c",&map[i][j]);
if(map[i][j]!='X'){
map[i][j]-='0';
cnt[map[i][j]]++;
}else map[i][j]=10;
}
scanf("\n");
}
fo(i,0,m+1)map[i][0]=map[i][n+1]=10;
fo(j,0,n+1)map[0][j]=map[m+1][j]=10;
dfs(0,0);
printf("%d %d",ans1,ans2);
return 0;
}