P1123 取数游戏
我理解的题目意思
一个 N×M 的由非负整数构成的数字矩阵,你需要在其中取出若干个数字,使得取出的任意两个数字不相邻(若一个数字在另外一个数字相邻 8 个格子中的一个即认为这两个数字相邻),求取出数字和最大是多少。
$$1≤N,M≤6,1≤T≤20,ai,j≤10^5$$解题思路
注意到数据量很小,可以dfs最大的数字和,维护一个chosen数组做一个待选择数字是否有相邻数字被选择的判断。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
int t, n, m, ans;
int a[10][10];
// 检查 (x,y) 是否与已选的格子相邻
bool ok(int x, int y, bool chosen[10][10])
{
for (int dx = -1; dx <= 1; dx++)
{
for (int dy = -1; dy <= 1; dy++)
{
if (dx == 0 && dy == 0)
continue;
int nx = x + dx;
int ny = y + dy;
if (nx >= 1 && ny >= 1 && nx <= n && ny <= m && chosen[nx][ny])
return false;
}
}
return true;
}
void dfs(int x, int y, int sum, bool chosen[10][10])
{
if (x > n)
{
ans = max(ans, sum);
return;
}
int nx = (y == m) ? x + 1 : x;
int ny = (y == m) ? 1 : y + 1;
dfs(nx, ny, sum, chosen);
if (ok(x, y, chosen))
{
chosen[x][y] = true;
dfs(nx, ny, sum + a[x][y], chosen);
chosen[x][y] = false;
}
}
int main()
{
cin >> t;
while (t--)
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
ans = 0;
bool chosen[10][10] = {};
dfs(1, 1, 0, chosen);
cout << ans << endl;
}
return 0;
}