对于这个题感觉是一个比较典型的dfs.本题的状态是 对于每个数字你可以选也可以不选,但是一旦你选定某个数字之后,他会对其周围的数字产生影响所以一定要标记好(注意这里标记的时候不能用 布尔数组 一定要用一个整形的数组,因为可能出现两个数中间的数本来不应该选但是最后选上的错误)
例如:
当单步运行的时候如果到了 选10,然后它会继续堆zhai,然后出zhai,如果取17过后,再复原的时候,3对应的类型就会变成 false,所以也就会把3选上 但是这样是不对的。所以,我们要利用整形的数组。
接下来的难点就是怎样去遍历了,这一点没啥好说的 因为我也是看题解的。题解大佬是 先对列进行遍历,然后换行,到最后一个点的时候就返回。
接下来就是 对于每个数 取和不取的两种状态:
完整的代码如下:
#include<iostream> #include<math.h> using namespace std; int a[8][8]; int b[8][8]; int p,q; const int d[8][2]={1,0,-1,0,0,1,0,-1,1,1,-1,1,1,-1,-1,-1}; //int d_x[8] = {0,0,1,1,1,-1,-1,-1}; //int d_y[8] = {1,-1,0,1,-1,0,-1,1}; int sum,sm; int max(int x,int y) { return (x > y) ? x : y; } void dfs(int m,int n){ if(n == q+1) { dfs(m+1,1); return; } if(m == p+1) { sum = max(sum,sm); return; } dfs(m,n+1); // 不取数字 if(b[m][n] == 0){ //不能用布尔数组 会重叠 sm += a[m][n]; for(int i = 0;i < 8;i++){ b[m + d[i][0]][n + d[i][1]]++; } dfs(m,n+1); //取这个数字 sm -= a[m][n]; for(int i = 0;i < 8;i++){ b[m + d[i][0]][n + d[i][1]]--; } } } int main(){ int n; cin>>n; while(n--){ cin>>p>>q; for(int i = 1;i <= p;i++) for(int j = 1;j <= q;j++) cin>>a[i][j]; sum = 0; dfs(1,1); cout<<sum<<endl; } return 0; }
okok 加油小灰灰 加油!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
标签:洛谷,int,题解,sum,dfs,取数,++,sm From: https://www.cnblogs.com/fighting-huihui/p/17064104.html