题目描述
一个 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; }