//开始对回溯有了点概念,
//即消除这点被取过造成的状态改变,使每次搜索都用的是最初的状态
#include <iostream> #include <set> #include <vector> #include <cmath> #include <cstdio> #include <cstring> #include <algorithm> #define ll long long using namespace std; const int M = 1e3 + 1; int a[M][M]; int vis[M][M];//标志,表示周围有多少个被取了的点 int n, m; int mx = 0;//存储最大值 int ans; inline void dfs(int x, int y)//x,y代表坐标 {//搜索方式为逐行逐个点的搜索 if (x > n) {//当已经越界 mx = max(mx, ans);//得到最大的值 return ; } if (y > m) {//换下一行,下一个点继续暴搜 dfs(x + 1, 1); return; } dfs(x, y + 1);//搜索下一个点,表示直接跳过这个点,去搜索下一个点 if (vis[x][y] == 0) {//周围没有取过的点 ans += a[x][y];//加上改点 //把该点附近的值全部变1 for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (i == 0 && j == 0) { continue; } vis[x + i][y + j] ++; } } dfs(x, y + 1);//变1后搜索 //回溯,使状态变回刚才那样 for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (i == 0 && j == 0) { continue; } vis[x + i][y + j] --; } } ans -= a[x][y]; // dfs(x,y+1); } } int main() { int t; cin >> t; while (t--) { memset(a, 0, sizeof(a));//每次都要 memset(vis, 0, sizeof(vis));//千万别忘了 mx = 0;//每次都要归0,否则又是上一次的 cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> a[i][j]; } } dfs(1, 1);//从坐标1,1开始搜索 cout << mx << endl; } }