P1123 取数游戏

取数游戏

题目描述

一个 N × M N\times M N×M 的由非负整数构成的数字矩阵,你需要在其中取出若干个数字,使得取出的任意两个数字不相邻(若一个数字在另外一个数字相邻 8 8 8 个格子中的一个即认为这两个数字相邻),求取出数字和最大是多少。

输入格式

第一行有一个正整数 T T T,表示了有 T T T 组数据。

对于每一组数据,第一行有两个正整数 N N N M M M,表示了数字矩阵为 N N N M M M 列。

接下来 N N N 行,每行 M M M 个非负整数,描述了这个数字矩阵。

输出格式

T T T 行,每行一个非负整数,输出所求得的答案。

样例 #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 ] 75 63 10 29 29 [ 92 ] 14 [ 21 ] 68 71 56 8 67 [ 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 , ≤ 3 1\le N, \le 3 1N,3
  • 对于 40 % 40\% 40%的数据, 1 ≤ N , M ≤ 4 1\le N,M\le 4 1N,M4
  • 对于 60 % 60\% 60%的数据, 1 ≤ N , ≤ 5 1\le N, \le 5 1N,5
  • 对于 100 % 100\% 100%的数据, 1 ≤ N , M ≤ 6 1\le N, M\le 6 1N,M6 1 ≤ T ≤ 20 1\le T\le 20 1T20
  • P1123 取数游戏_第1张图片
#include
using namespace std;
int t,n,m,ans,maxn;
int a[37];
int vis[7][7];
void dfs(int x)
{
	if(x>=m*n){
		maxn=max(maxn,ans);
		return ;
	}
	dfs(x+1);
	if(vis[x/m+1][x%m+1]==0){
		ans+=a[x];
		for(int i=x/m;i<=x/m+2;i++){
			for(int j=x%m;j<=x%m+2;j++)
				vis[i][j]++;
		}
		dfs(x+1);
		ans-=a[x];
		for(int i=x/m;i<=x/m+2;i++){
			for(int j=x%m;j<=x%m+2;j++)
				vis[i][j]--;
		}
	}
}
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		for(int i=0;i<n*m;i++)cin>>a[i];
		memset(vis,0,sizeof vis);
		dfs(0);
		cout<<maxn<<endl;
		maxn=0,ans=0;
		memset(a,0,sizeof a);
	}
	return 0;
}

你可能感兴趣的:(暑假笔记,游戏,深度优先,图论)