解题思路:如果所有的数加起来是奇数,那么肯定不合法直接输出0。否则,从左上角开始dfs,当找到一组答案的数等于总和的一半且格子数小的时候更新答案;如果越界了剪枝,如果这个点来过剪枝,如果加上这个点已经不合法剪枝。
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
namespace IO{
inline LL read(){
LL o=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){o=o*10+c-'0';c=getchar();}
return o*f;
}
}using namespace IO;
const int N=10+7,M=1e4+7,INF=0x3f3f3f3f,mod=1e9+7,P=131;
int a[N][N];
bool st[N][N];
int cnt=INF;
int sum=0;
int n,m;
int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
void dfs(int s,int x,int y,int res){
if(s==sum/2&&cnt>res){
cnt=res;
return ;
}
for(int i=0;i<4;i++){
int tx=dx[i]+x,ty=dy[i]+y;
if(tx<0||tx>=n||ty<0||ty>=m)continue;
if(st[tx][ty])continue;
if(s+a[tx][ty]>sum/2)continue;
st[tx][ty]=1;
dfs(s+a[tx][ty],tx,ty,res+1);
st[tx][ty]=0;
}
}
int main(){
cin>>m>>n;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>a[i][j];
sum+=a[i][j];
}
}
if(sum&1){
cout<<0<<endl;
return 0;
}
st[0][0]=1;
dfs(a[0][0],0,0,1);
if(cnt==INF)cout<<0<<endl;
else cout<<cnt<<endl;
return 0;
}