题意:从左上角开始把给的格子分成两部分,两部分的和相同。问最少的左上角格子数。
思路:(dfs+回溯+剪枝)。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int map[12][12],n,m;
int vis[12][12];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int ans=1000;
int sum,flag=0;
void dfs(int u,int x,int cnt){
//cout<<x<<endl;
if(x==sum-x){
flag=1;ans=min(cnt,ans);
return;
}
if(x>sum-x) return;
for(int i=0;i<4;i++){
int ux=u/11+dx[i];
int uy=u%11+dy[i];
if(ux<0||uy<0||ux>n||uy>m) continue;
if(!vis[ux][uy]){
vis[ux][uy]=1;
dfs(ux*11+uy,x+map[ux][uy],cnt+1);
vis[ux][uy]=0;
}
}
}
int main(){
sum=0;
cin>>m>>n;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
cin>>map[i][j],sum+=map[i][j];
}
if(sum&1) printf("0\n");
else{
memset(vis,0,sizeof(vis));
vis[0][0]=1;
dfs(0,map[0][0],1);
if(!flag) printf("0\n");
else printf("%d\n",ans);
}
//左上角最少格子数目。
return 0;
}