取数游戏
题目描述
一个 N×MN\times MN×M 的由非负整数构成的数字矩阵,你需要在其中取出若干个数字,使得取出的任意两个数字不相邻(若一个数字在另外一个数字相邻 888 个格子中的一个即认为这两个数字相邻),求取出数字和最大是多少。
输入格式
第一行有一个正整数 TTT,表示了有 TTT 组数据。
对于每一组数据,第一行有两个正整数 NNN 和 MMM,表示了数字矩阵为 NNN 行 MMM 列。
接下来 NNN 行,每行 MMM 个非负整数,描述了这个数字矩阵。
输出格式
共 TTT 行,每行一个非负整数,输出所求得的答案。
样例 #1
样例输入 #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
样例输出 #1
271
172
99
提示
样例解释
对于第一组数据,取数方式如下:
[67]7563102929[92]14[21]687156867[91]25\begin{matrix} [67] & 75 & 63 & 10 \\ 29 & 29 & [92] & 14 \\ [21] & 68 & 71 & 56 \\ 8 & 67 & [91] & 25 \\ \end{matrix}[67]29[21]87529686763[92]71[91]10145625
数据范围及约定
- 对于20%20\%20%的数据,1≤N,M≤31\le N, M \le 31≤N,M≤3;
- 对于40%40\%40%的数据,1≤N,M≤41\le N, M\le 41≤N,M≤4;
- 对于60%60\%60%的数据,1≤N,M≤51\le N, M\le 51≤N,M≤5;
- 对于100%100\%100%的数据,1≤N,M≤61\le N, M\le 61≤N,M≤6,1≤T≤201\le T\le 201≤T≤20。
只是一道经典深搜题,深搜本质上就是两种方案:选或不选
既然只有选或不选,那么我们只需要增加一个判断,判断我们的选择是否合法。
合法先选上,不合法则不选,如果后面回溯寻找到了更好的方案,则将以前方法舍去,记录新的方法。接下来上代码。
Code
#include <bits/stdc++.h>
using namespace std;
int n,m,ans,sum;
int w[15][15];
int a[15][15];
bool check(int x, int y){
for(int i=x-1;i<=x+1;i++){
for(int j=y-1;j<=y+1;j++){
if(a[i][j] == 1){
return 0;
}
}
}
return true;
}
void dfs(int x, int y,int sum){
if(x > n){
ans = max(ans,sum);
return ;
}
int xx = x, yy = y + 1;
if(yy > m){
xx++;
yy = 1;
}
if(check(x,y)){
a[x][y] = 1;
dfs(xx,yy,sum + w[x][y]);
}
a[x][y] = 0;
dfs(xx,yy,sum);
}
int main(){
int kkksc03;
cin >> kkksc03;
while(kkksc03--){
cin >> n >> m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin >> w[i][j];
}
}
ans = 0;
dfs(1,1,0);
cout << ans << endl;
}
return 0;
}