首页 > 其他分享 >DFS判重问题

DFS判重问题

时间:2024-03-10 20:55:41浏览次数:23  
标签:判重 return int sum DFS st 问题 le dfs

奇怪的电梯(洛谷)

题目背景

感谢 @yummy 提供的一些数据。

题目描述

呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第 \(i\) 层楼(\(1 \le i \le N\))上有一个数字 \(K_i\)(\(0 \le K_i \le N\))。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如: \(3, 3, 1, 2, 5\) 代表了 \(K_i\)(\(K_1=3\),\(K_2=3\),……),从 \(1\) 楼开始。在 \(1\) 楼,按“上”可以到 \(4\) 楼,按“下”是不起作用的,因为没有 \(-2\) 楼。那么,从 \(A\) 楼到 \(B\) 楼至少要按几次按钮呢?

输入格式

共二行。

第一行为三个用空格隔开的正整数,表示 \(N, A, B\)(\(1 \le N \le 200\),\(1 \le A, B \le N\))。

第二行为 \(N\) 个用空格隔开的非负整数,表示 \(K_i\)。

输出格式

一行,即最少按键次数,若无法到达,则输出 -1

样例 #1

样例输入 #1

5 1 5
3 3 1 2 5

样例输出 #1

3

提示

对于 \(100 \%\) 的数据,\(1 \le N \le 200\),\(1 \le A, B \le N\),\(0 \le K_i \le N\)。

本题共 \(16\) 个测试点,前 \(15\) 个每个测试点 \(6\) 分,最后一个测试点 \(10\) 分。







  • 难度不大,就是注意剪枝
    分歧之处在于判重,我的版本判重是用st数组来,对于小数据来说,没问题,但量大了,会MLE
    优化之处就是用cnt数组记录每个点的步数,初始化为1e9,被更新,那么这就是第一次的点,在剪枝里用if(sum >= cnt[u]) return; 剪枝掉重复到这个点的分支,也就是判重了
  • 我还一直想错在哪,感觉也行,没问题,实际是优化不明显,因为回退到最初点,又会让一些点继续dfs,而实际早走过了,cnt数组就体现优势了

完整代码

#include <iostream>
using namespace std;
const int N = 210;
int g[N];
int n, a, b;
int ans = 1e9;
int cnt[N];
int sum;

void dfs(int u,int sum)
{
	if (sum >= ans) return;
	if (u < 1 || u > n) return;
	if (sum >= cnt[u]) return;
	if (u == b)
	{
		ans = sum;
		return;
	}

	cnt[u] = sum;
	dfs(g[u] + u;, sum + 1);
	dfs(u - g[u];, sum + 1);
}

int main()
{
	cin >> n >> a >> b;
	for (int i = 1; i <= n; i++) cin >> g[i], cnt[i] = 1e9;

	dfs(a,  0);

	if (ans == 1e9) cout << -1;
	else cout << ans;

	return 0;
}

DFS---MLE版本

#include <iostream>
using namespace std;
const int N = 210;
int g[N];
bool st[N];
int n, a, b;
int ans = 1e9;
int sum;

void dfs(int u, int sum)
{

	if (sum >= ans) return;
	if (u < 1 || u > n) return;
	if (st[u]) return;
	if (u == b)
	{
		ans = sum;
		return;
	}

	int x = g[u] + u;
	int y = u - g[u];

	st[u] = true;
	dfs(x, sum + 1);
	dfs(y, sum + 1);
	st[u] = false;
}

int main()
{
	cin >> n >> a >> b;
	for (int i = 1; i <= n; i++) cin >> g[i];

	dfs(a, 0);

	if (ans == 1e9) cout << -1;
	else cout << ans;

	return 0;
}

正确BFS版本

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int N = 210;
int g[N];
int dist[N];
bool st[N];
int n, a, b;

void bfs()
{
	memset(dist, -1, sizeof dist);
	queue<int> q;
	q.push(a);
	dist[a] = 0;
	st[a] = true;

	while (q.size())
	{
		auto t = q.front();
		q.pop();
		if (t == b) return;
		
		for (int i = 0; i < 2; i++)
		{
			if (i == 0)
			{

				int x = g[t] + t;
				if (x > n) continue;
				if (st[x]) continue;
				st[x] = true;
				dist[x] = dist[t] + 1;
				q.push(x);
			}
			else
			{
				int y = t - g[t];
				if (y <= 0) continue;
				if (st[y]) continue;
				st[y] = true;
				dist[y] = dist[t] + 1;
				q.push(y);
			}
		}
	}
}
int main()
{
	cin >> n >> a >> b;
	for (int i = 1; i <= n; i++) cin >> g[i];

	bfs();

	cout << dist[b];

	return 0;
}

标签:判重,return,int,sum,DFS,st,问题,le,dfs
From: https://www.cnblogs.com/xingzhuz/p/18064779

相关文章

  • MPU6050 memcmp(firmware+ii, cur, this_write)初始化问题|MPU6050固件库加载问题
    使用MPU6050dmp固件库时候报错:MPU6050固件库加载,最后运行到“memcmp(firmware+ii,cur,this_write)”无法通过!从网上查找了相同问题的解答,发现修改了IIcSDA与SCL端口但是头文件的中的宏定义没有修改未修改之前的端口:修改之后的端口:这里在修改宏定义的时候遇到了些问......
  • 动态规划 背包问题
    分类:01背包 完全背包01:多个物品,每个只有一个,物品有weight和value。背包载重有限制,问最多能放多少;完全:多个物体,每个有无数个dp[i][j]的含义:在【0,i】这么多物品中,放入载重为j的背包内的最大价值。物品/载重载重0载重1载重2载重3物品0    物品1 ......
  • 常见问题解决 --- 海康OpenAPI安全认证库的demo运行报错
    我要开发一个对接海康isc平台的oss的api,发现需要有海康登录库和ak、sk的配合才能完成。在海康官方下载OpenAPI安全认证库(JAVA)V1.1.11,解压后用idea打开demo发现一对报错。解决办法:1.修复基本的错误。比如包名报错,应该是  packagega; 2.修复maven依赖导入报错。首先是artem......
  • “田由甲” - Kafka重复消费线上问题暴雷
    Kafka作为一款高性能、分布式的消息队列系统,在大数据领域被广泛应用。然而,在使用Kafka时,重复消费问题是一个常见的挑战,可能会对系统的数据一致性和业务逻辑造成影响。我知道Kafka这个名词时还是在2019年刚工作的时候,但那时候公司使用的消息队列体量很小,所以只用了activeMq,我......
  • FPGA的DAC转换部分遇到的问题
    利用线性序列机根据时序图和手册中的输出值的对应关系。DAC这边的知识基本相同。在验证的时候发现了问题,反推仿真的时候发现了,子啊lsm_cnt线性序列机计数的33到了之后还有一位,发现是set_en的问题,因为set_en使能才能计数。这边是正确的波形图和代码对应always@(posedgeclko......
  • WordPress:常见问题及解决方案
    解决头像不显示问题默认头像效果:Gavatar的头像在国内不能正常访问,如图:设置:把以下php代码添加到模板函数funtions.php文件中if(!function_exists('get_cravatar_url')){/***把Gravatar头像服务替换为Cravatar*@paramstring$url*@return......
  • Ubuntu安装Nginx,并且解决问题
    Ubuntu安装Nginx,并且解决问题安装Nginxnginx-1.12.2首先下载Nginx的压缩包Nginx的压缩包然后在Ubuntu中创建一个目录,开始解压tar-zxvfnginx-1.12.2.tar.gz解压结束后在编译和安装Nginx之前,您需要安装一些依赖库。通常,Nginx需要openssl、pcre和zlib等库。sudoaptupdate......
  • Acwing166 数独题解 - DFS剪枝优化
    166.数独-AcWing题库题意数独是一种传统益智游戏,你需要把一个9×9的数独补充完整,使得数独中每行、每列、每个3×3的九宫格内数字1∼9均恰好出现一次。请编写一个程序填写数独。思路搜索+剪枝(优化搜索顺序、位运算)优化搜索顺序:很明显,我们肯定是从当前能填合法......
  • 跨域问题
    一、什么是跨域问题在浏览器端进行Ajax请求时会出现跨域问题,那么什么是跨域,如何解决跨域呢?先看浏览器端出现跨域问题的现象,如下图所示1.什么是跨域问题?跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。2.什么......
  • spring-boot spring-security oauth2 /oauth/token报401,403 问题
    2024-03-1012:20:55.281INFO58776---[nio-8002-exec-2]o.s.web.servlet.DispatcherServlet:InitializingServlet'dispatcherServlet'2024-03-1012:20:55.283INFO58776---[nio-8002-exec-2]o.s.web.servlet.DispatcherServlet:Completedi......