题目描述
一个 N×M 的由非负整数构成的数字矩阵,你需要在其中取出若干个数字,使得取出的任意两个数字不相邻(若一个数字在另外一个数字相邻 8 个格子中的一个即认为这两个数字相邻),求取出数字和最大是多少。
输入格式
第一行有一个正整数 T,表示了有 T 组数据。
对于每一组数据,第一行有两个正整数 N 和 M,表示了数字矩阵为 N 行 M 列。
接下来 N 行,每行 M 个非负整数,描述了这个数字矩阵。
输出格式
共 T 行,每行一个非负整数,输出所求得的答案。
输入输出样例
输入 #1复制
3
4 4
67 75 63 10
29 29 92 14
21 68 71 56
8 67 91 25
2 3
87 70 85
10 3 17
3 3
1 1 1
1 99 1
1 1 1
#include<bits/stdc++.h>//万能头文件
using namespace std;
const int N = 10;
int dx[8] = {-1,-1,-1,0,0,1,1,1},dy[8]={-1,0,1,-1,1,-1,0,1};//方向数组用来控制搜索时的方向
int n,m,sum,res;
int st[N][N];//本题不能用bool存 因为 每选一个点就更新周围8个点的状态 一点可能不止被更新一次
int g[N][N];
void dfs(int x,int y){//搜索函数,表示搜索点(x,y)
if(y == m+1){ //当y到边界时,搜索下一行
dfs(x+1,1);
return;
}
if(x == n+1){// 搜索完整个矩阵 处理最大值 res 存放的全局最大值 ans 存放当前最大值
res = max(sum,res);
return;
}
dfs(x,y+1);// 不取此数的情况
if(st[x][y]==0){ //取此数的情况(需保证此数周围没有取其他数)
sum += g[x][y]; //如果选这个数则更新的
for(int i=0;i<8;i++){ //标记周围的数
int a=x+dx[i];
int b=y+dy[i];
st[a][b]++;
}
dfs(x,y+1);
for(int i=0;i<8;i++){ //回溯
int a=x+dx[i];
int b=y+dy[i];
st[a][b] --;
}
sum-=g[x][y];
}
}
int main(){
int T ;
cin>>T;
while(T--){
memset(g,0,sizeof g);
memset(st,0,sizeof st );//在做每个数据前都要初始化数组
cin>>n>>m;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
cin>>g[i][j];
}
}
res = 0;
dfs(1,1);//从点(1,1)开始搜索
printf("%d\n",res);//输出答案
}
return 0;
}