P1123 取数游戏(dfs算法)

news/2024/7/20 21:49:58 标签: 算法, 数据结构, c++, 深度优先

题目描述

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

输入格式

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

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

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

输出格式

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

输入输出样例

输入 

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

输出 

271
172
99
 

数据范围及约定

  • 对于20%20%的数据,1≤N,M≤3;
  • 对于40%40%的数据,1≤N,M≤4;
  • 对于60%60%的数据,1≤N,M≤5;
  • 对于100%100%的数据,1≤N,M≤6,1≤T≤20。

思路 : 

此题为n皇后问题的简单版,算法为dfs,只要枚举每行每列元素就可,分两种情况,取这个元素和不能取这个元素,题目中所说的,相邻的八个格子元素不能取是这个意思如图

×的八个方向不能取。接下来我们看代码


AC代码: 

#include<iostream>
#include<cmath>
#include<cstring>

using namespace std;

int dx[8] = {-1,-1,-1,0,0,1,1,1},dy[8] = {-1,0,1,-1,1,-1,0,1};
const int N = 10;
int g[N][N];//数字数组 
int st[N][N];//标记数组 
int mx,ans,n,m;

void dfs(int x,int y)
{
	//如果搜到该行的最后一列就换下一行第一列 
	if(y == m + 1)
	{
		x++,y=1;
	}
	//所有行列搜完了 进行输出 
	if(x == n + 1)
	{
		mx = max(ans,mx);
		return; 
	}
	//不放 
	dfs(x,y+1);
	//放
	if(!st[x][y])
	{
		ans += g[x][y];
		for(int i=0;i<8;i++)
		{
			st[x+dx[i]][y+dy[i]]++;
		}
		dfs(x,y+1);
		for(int i=0;i<8;i++)
		{
			st[x+dx[i]][y+dy[i]]--;
		}
		ans -= g[x][y];
	} 
}

int main()
{
	cin.tie(0)->ios::sync_with_stdio(false);//快读 
	int t;
	cin >> t;
	while(t --)
	{
		//注意:每次使用完记得清0 
		memset(g,0,sizeof(g));
		memset(st,0,sizeof(st));
		cin >> n >> m;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				cin >> g[i][j];
			}
		}
		mx = 0;//每次搜完需要变成0,方便下次使用不会错 
		dfs(1,1);//从第一个行第一列第一个元素开始搜索 
		cout << mx << endl;
	}
	return 0;
}

注意:此题我们不能使用bool类型去进行标记,我们可以用一个int类型的变量来记录,当这个数被访问时,该变量自增,当回溯时,该变量自减==>所以当该变量为零时,该数未被访问。(至于这个我们可以手动模拟一下就能有结果)


http://www.niftyadmin.cn/n/5475581.html

相关文章

WebGL异步绘制多点

异步绘制线段 1.先画一个点 2.一秒钟后&#xff0c;在左下角画一个点 3.两秒钟后&#xff0c;我再画一条线段 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"…

LeetCode-2009. 使数组连续的最少操作数【数组 哈希表 二分查找 滑动窗口】

LeetCode-2009. 使数组连续的最少操作数【数组 哈希表 二分查找 滑动窗口】 题目描述&#xff1a;解题思路一&#xff1a;正难则反滑动窗口解题思路二&#xff1a;0解题思路三&#xff1a;0 题目描述&#xff1a; 给你一个整数数组 nums 。每一次操作中&#xff0c;你可以将 n…

el-table-column 有两个input怎么校验

在el-table-column中使用两个input进行数据验证时&#xff0c;可以通过Vue的双向数据绑定和Element UI的表单验证机制来实现。以下是一个简单的示例&#xff1a; 使用el-form和el-form-item来包裹el-table&#xff0c;以便使用表单验证功能。 在el-table-column中使用template…

比特币4种地址格式

原生隔离见证、嵌套隔离见证、Taproot和Legacy都是比特币网络中不同的比特币地址格式或交易类型。每一种都有自己的特点和好处: 1.本地隔离见证(Segregated Witness Bech32): 钱包的支持 Phantom, Leather, Unisat, Okex Wallet 本地隔离见证地址以 bc1开始&#xff0c;也称为…

干货分享|连续翻页:利用转场实现视觉特效

除了在不同的镜头间产生过渡效果以外&#xff0c;我们也可以利用转场预设制作一些特殊的视觉特效。本节就使用最简单的滑动转场预设制作连续翻页的动画效果。 1.在达芬奇里新建一个项目&#xff0c;按快捷键CtrlI导入实例教学素材。执行“DaVinci Resolve”菜单中的“偏好设置…

42.基于SpringBoot + Vue实现的前后端分离-服装销售平台管理系统(项目 + 论文)

项目介绍 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的交换和信息流通显得特别重要。因此&#xff0c;开发合适的服装销售平台成为企业必然要走的一步棋。开发合适的服…

云联惠涉嫌传销——时代的牺牲品 积分合法化!

大家好&#xff0c;我是吴军&#xff0c;来自一家专注于软件开发的公司&#xff0c;担任产品经理的职务。 今天&#xff0c;我想和大家聊一聊曾经风光一时的云联惠。这个平台在其巅峰时期&#xff0c;吸引了高达一千万的用户&#xff0c;资金规模更是达到了惊人的6000亿。 记得…

第二章:类型转换

类型转换&#xff08;P44&#xff09; 在八种基本数据类型中&#xff0c;除boolean型之外&#xff0c;其他七种类型之间都可以相互转换。小容量向大容量的转换&#xff0c;称为自动类型转换。容量从小到大排序&#xff1a;byte < short / char < int < long < flo…