当前位置: 首页 > news >正文

笔记:蓝桥杯python搜索(3-2)——DFS剪支和记忆化搜索

目录

 一、DFS剪支

二、例题

P2942 数字王国之军训军队

 P3075 特殊的多边形

三、记忆化搜索

四、例题

例题 P3820 混境之地

P216 地宫取宝


 一、DFS剪支

  • 在搜索过程中,如果需要完全遍历所有情况可能需要很多时间
  • 在搜索到某种状态时,根据当前状态判断出后续无解,则该状态无需继续深入搜索
  • 例如:给定N个正整数,求出有多少个子集之和小于等于K。在搜索过程中当前选择的数字和已经超过K则不需要继续搜索。
  • 可行性剪枝:当前状态和题意不符,并且往后的所有情况和题意都不符,那么就可以进行剪枝。
  • 最优性剪枝:在搜索过程中,当前状态已经不如已经找到的最优解,也可以剪枝,不需要继续搜索。

二、例题

P2942 数字王国之军训军队

数字王国开学了,它们也和我们人类一样有开学前的军训,现在一共有 n 名学生,每个学生有自己的一个名字 ai​(数字王国里的名字就是一个正整数,注意学生们可能出现重名的情况),此时叛逆教官来看了之后感觉十分别扭,决定将学生重新分队。

排队规则为:将学生分成若干队,每队里面至少一个学生,且每队里面学生的名字不能出现倍数关系(注意名字相同也算是倍数关系)。

现在请你帮忙算算最少可以分成几队?

例:有 4 名学生 (2,3,4,4),最少可以分成 (2,3)、(4)、(4) 共 3 队。

输入格式

第一行包含一个正整数 n,表示学生数量。

第二行包含 n 个由空格隔开的整数,第 i 个整数表示第 i 个学生的名字 ai​。

输出格式

输出共 1 行,包含一个整数,表示最少可以分成几队。

DFS 搜索,枚举每个学生分到每个组内

可行性剪枝:要满足题目条件

最优性剪枝:判断当前状态是否比 ans 更劣


def check(x,group):for y in group:if x%y ==0 or y%x==0:return Falsereturn Truedef dfs(depth):if depth==n:global answeranswer=min(answer,len(Groups))returnfor every_group in Groups:if check(a[depth],every_group):every_group.append(a[depth])dfs(depth+1)every_group.pop()Groups.append([a[depth]])dfs(depth+1)Groups.pop()n=int(input())
a=list(map(int,input().split()))
Groups=[]
answer=n
dfs(0)
print(answer)
# 判断x能否加入group组   
def check(x, group):# 要保证不能存在倍数关系for y in group:if x % y == 0 or y % x == 0:return Falsereturn True# depth表示当前为第depth个学生   
def dfs(depth):global ans# 最优性剪枝:当前已经比ans大,说明该策略不可行if len(Groups) > ans:returnif depth == n:ans = min(len(Groups), ans)returnfor each_group in Groups:# 枚举第depth个学生能否加入当前组each_group# 剪枝:必须满足题意if check(a[depth], each_group):each_group.append(a[depth])dfs(depth + 1)each_group.pop()# 单独作为一组,将 ​a[depth]​ 作为一个新的分组添加,即 ​Groups.append([a[depth]])​Groups.append([a[depth]])dfs(depth + 1)Groups.pop()n = int(input())   
a = list(map(int, input().split()))   
# ans表示最少能分多少队   
ans = n# Groups表示分组情况   
Groups = []   
dfs(0)   
print(ans)

 P3075 特殊的多边形

假设一个 n 边形 n 条边为 a1,a2,a3,⋯,an​,定义该 n 边形的值 v=a1×a2×a3×⋯×an。

定义两个 n 边形不同是指至少有一条边的长度在一个 n 边形中有使用而另一个 n 边形没有用到,如 n 边形 (3,4,5,6)和 (3,5,4,6) 是两个相同的 n 边形,(3,4,5,6)和 (4,5,6,7) 是两个不相同的 n 边形。

现在有 t 和 n,表示 t 个询问并且询问的是 n 边形,每个询问给定一个区间 [l,r],问有多少个 n 边形(要求该 n 边形自己的 n 条边的长度互不相同)的值在该区间范围内。

输入格式

第一行包含两个正整数 t、n,表示有 t 个询问,询问的是 n 边形。

接下来 t 行,每行有两个空格隔开的正整数 l、r,表示询问区间 [l,r]。

输出格式

输出共 t 行,第 i行对应第 i 个查询的 n 边形个数。

  • 先考虑简单版:乘积为 v 有多少种 n 边形

  • DFS 处理出所有乘积对应的所有可能

    • 维护一个递增的边长序列(唯一性)

    • 枚举第 i 边的长度,最小最大范围(剪枝)

    • 最终 check 是否满足 N 边形:

      • 最小的 N - 1 条边之和大于第 N 边

  • 预处理+前缀和 O(1)查询答案


import os
import sys# 请在此输入您的代码
def dfs(depth, last_val, tot, mul):""":param depth:    第depth条边长:param last_val: 上一边长长度:param tot:      累计和:param mul:      累计乘积"""if depth == n:# 前n-1条边之和大于第n条边if tot - path[-1] > path[-1]:ans[mul] += 1returnfor i in range(last_val + 1, 100001):# 最优性剪枝, 后续还有n-depth个数字, 每个数字都要>=i# 累计乘积要不超过100000: mul * (i ** (n - depth))if mul * (i ** (n - depth)) > 100000:breakpath.append(i)dfs(depth + 1, i, tot + i, mul * i)path.pop()t, n = map(int, input().split())
ans = [0] * 100001
path = []
dfs(0, 0, 0, 1)for i in range(1, 100001):ans[i] += ans[i - 1]
for _ in range(t):l, r = map(int, input().split())print(ans[r] - ans[l - 1])

三、记忆化搜索

  • 记忆化:通过记录已经遍历过的状态的信息,从而避免对同一状态重复遍历的搜索实现方式。
  • 记忆化=dfs+额外字典
    • 如果先前已经搜索过:直接查字典,返回字典中结果
    • 如果先前没有搜索过:继续搜索,最终将该状态结果记录到字典中
  • 斐波那契数列:设F[0] = 1, F[1] = 1, F[n] = F[n - 1] + F[n - 2],求F[n],结果对1e9 + 7取模。 0 <= n <= 10000
  • 样例输入: 5000
  • 样例输出: 976496506
def f(n):if n==0 or n==1:return 1return (f(n-1)+f(n-2))%(1e9+7)
n=int(input())
print(f(n))
# 直接递归存在大量重复计算

计算 F(5) 时,要先算 F(4) 和 F(3);算 F(4) 又需算 F(3) 和 F(2),这里 F(3) 就被重复计算了。随着 n 增大,像 F(2)F(3) 这类中间结果会被反复多次计算,导致时间复杂度呈指数级增长,效率极低。

  • 每次搜索时将当前状态答案记录到字典中
  • 后续搜索直接返回结果
import sys
sys.setrecursionlimit(100000)# 记忆化1
dic={0:1,1:1}
def f(n):if n in dic.keys():return dic[n]dic[n]=(f(n-1)+f(n-2))%1000000007return dic[n]
n=int(input())
print(f(n))

 

from functools import lru_cache#记忆化搜索2
@lru_cache(maxsize=None)
from functools import lru_cache# 记忆化2
@lru_cache(maxsize=None)
def f(n):if n==0 or n==1:return 1return f(n-1)+f(n-2)
n=int(input())
print(f(n))

四、例题

例题 P3820 混境之地

小蓝有一天误入了一个混境之地。

好消息是:他误打误撞拿到了一张地图,并从中获取到以下信息:

  1. 混境之地是一个 n⋅m 大小的矩阵,其中第 i 行第 j 列的的点 hij​ 表示第 i 行第 j 列的高度。

  2. 他现在所在位置的坐标为 (A,B) ,而这个混境之地出口的坐标为 (C,D) ,当站在出口时即表示可以逃离混境之地。

  3. 小蓝有一个喷气背包,使用时,可以原地升高 k 个单位高度。

坏消息是:

  1. 由于小蓝的体力透支,所以只可以往低于当前高度的方向走。

  2. 喷漆背包燃料不足,只可以最后使用一次。

小蓝可以往上下左右四个方向行走,不消耗能量。

小蓝想知道他能否逃离这个混境之地,如果可以逃离这里,输入 Yes ,反之输出 No 。


输入格式

第 1 行输入三个正整数 n,m 和 k , n,m 表示混境之地的大小, k 表示使用一次喷气背包可以升高的高度。

第 2 行输入四个正整数 A,B,C,D ,表示小蓝当前所在位置的坐标,以及混境之地出口的坐标。

第 3 行至第 n+2 行,每行 m 个整数,表示混境之地不同位置的高度。

输出格式

输出数据共一行一个字符串:

  • 若小蓝可以逃离混境之地,则输出 Yes 。

  • 若小蓝无法逃离混境之地,则输出 No 。

走到(x,y),z表示是否使用喷气背包

当x,y,z固定时,具有唯一解,因此可以使用记忆化搜索

时间复杂度<x,y,z>三元组数量:1000*1000*2

from functools import lru_cache#记忆化搜索2
@lru_cache(maxsize=None)
def dfs(x, y, z):# print(x, y, z)# 当前处于(x,y), z表示是否使用喷气背包# 如果能逃离, 返回True, 否则返回Falseif x == C - 1 and y == D - 1:return True#没走到终点,四个方向判断for i in range(4):xx, yy = x + dir[i][0], y + dir[i][1]#不能越界if xx < 0 or xx >= n or yy < 0 or yy >= m:continue#新坐标比旧坐标低,走到新坐标(xx,yy)if Map[xx][yy] < Map[x][y]:if dfs(xx, yy, z):return True#在(x,y)处使用喷气背包elif Map[xx][yy] < Map[x][y] + k and z == False:if dfs(xx, yy, True):return Truereturn False# 四个方向
dir = [(1, 0), (0, 1), (-1, 0), (0, -1)]
n, m, k = map(int, input().split())
A, B, C, D = map(int, input().split())
Map = []
for i in range(n):Map.append(list(map(int, input().split())))
if dfs(A - 1, B - 1, False):print("Yes")
else:print("No")

P216 地宫取宝

X 国王有一个地宫宝库。是 n×m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。

地宫的入口在左上角,出口在右下角。

小明被带到地宫的入口,国王要求他只能向右或向下行走。

走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。

当小明走到出口时,如果他手中的宝贝恰好是 k 件,则这些宝贝就可以送给小明。

请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这 k 件宝贝。


输入描述

输入一行 3 个整数,用空格分开:n,m,k (1≤n,m≤50,1≤k≤12)。

接下来有 n 行数据,每行有m 个整数 Ci (0≤Ci≤12) 代表这个格子上的宝物的价值。

输出描述

要求输出一个整数,表示正好取 k 个宝贝的行动方案数。该数字可能很大,输出它对 10^9+7 取模的结果。

从(x,y)出发,先前已经有宝物z件,已有的最大宝物价值为w的方案数记为dfs(x,y,z,w)

只要确定四元组,就确定当前的方案数

答案=dfs(1,1,0,-1)

最终点=dfs(n,m,z,?) or dfs(n,m,z - 1,?)

(x,y)处可选,可不选,然后可以往右走或者往下走

from functools import lru_cache@lru_cache(maxsize=None)   
def dfs(x, y, z, w):#从(x,y)出发,先前已有z件宝物,已有宝物最大价值为w#走到终点if x == n and y == m:#当前不需要选择if z == k:return 1#当前需要选择if z == k - 1:if w < a[x][y]:return 1#其他情况,均为0return 0ans = 0#遍历两个方向for delta_x, delta_y in [(1, 0), (0, 1)]:xx, yy = x + delta_x, y + delta_yif xx <= n and yy <= m:# 当前不选择ans += dfs(xx, yy, z, w)# 当前选择if w < a[x][y]:ans += dfs(xx, yy, z + 1, a[x][y])return ans % 1000000007n, m, k = map(int, input().split())   
a = [[0]*(m+1)]   
for i in range(n):a.append([0] + list(map(int, input().split())))   
print(dfs(1, 1, 0, -1))

相关文章:

笔记:蓝桥杯python搜索(3-2)——DFS剪支和记忆化搜索

目录 一、DFS剪支 二、例题 P2942 数字王国之军训军队 P3075 特殊的多边形 三、记忆化搜索 四、例题 例题 P3820 混境之地 P216 地宫取宝 一、DFS剪支 在搜索过程中&#xff0c;如果需要完全遍历所有情况可能需要很多时间在搜索到某种状态时&#xff0c;根据当前状态判断…...

ChatBox+硅基流动Deepseek_R1开源API 满血(671B)部署教程,全程干货无废话

DeepSeek开源深度推理模型火爆发布&#xff0c;网络流量过大经常导致服务器崩溃&#xff0c;所以一般有两种方法解决这个问题 如果你的硬件支持&#xff0c;或者保密文档&#xff0c;保密单位&#xff0c;那么可以部署在本地端。但是再好的电脑也不能让DS满血复活&#xff0c;…...

35~37.ppt

目录 35.张秘书-《会计行业中长期人才发展规划》 题目​ 解析 36.颐和园公园&#xff08;25张PPT) 题目​ 解析 37.颐和园公园&#xff08;22张PPT) 题目 解析 35.张秘书-《会计行业中长期人才发展规划》 题目 解析 插入自定义的幻灯片&#xff1a;新建幻灯片→重用…...

畅快使用DeepSeek-R1的方法

腾讯云API接入Cherry Studio简明指南-畅快使用DeepSeek-R1 注意&#xff1a;腾讯云API针对deepseek限时免费&#xff08;后续即使收费也较为便宜&#xff0c;可以作为长期使用的方法&#xff09;&#xff0c;并且比华为的API要快不少。 一、获取腾讯云API密钥 登录并进入腾讯…...

【人工智能】Python中的序列到序列(Seq2Seq)模型:实现机器翻译

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 序列到序列(Seq2Seq)模型是自然语言处理(NLP)中一项核心技术,广泛应用于机器翻译、语音识别、文本摘要等任务。本文深入探讨Seq2Seq模…...

【算法】动态规划专题⑥ —— 完全背包问题 python

目录 前置知识进入正题模板 前置知识 【算法】动态规划专题⑤ —— 0-1背包问题 滚动数组优化 完全背包问题是动态规划中的一种经典问题&#xff0c;它与0-1背包问题相似&#xff0c;但有一个关键的区别&#xff1a;在完全背包问题中&#xff0c;每种物品都有无限的数量可用。…...

记一次基于manifest v3开发谷歌插件

背景 头疼在国际化功能普遍的前端项目中&#xff0c;如果你在处理或者在某一块功能上新增一些需求的时候&#xff0c;在没有国际化功能的页面中&#xff0c;我们随便复制一些文本&#xff0c;然后在vs code中全局搜索&#xff0c;很快就可以找到所要更改的代码文件在哪里&…...

C# OpenCvSharp 部署MOWA:多合一图像扭曲模型

目录 说明 效果 项目 代码 下载 参考 C# OpenCvSharp 部署MOWA&#xff1a;多合一图像扭曲模型 说明 算法模型的paper名称是《MOWA: Multiple-in-One Image Warping Model》 ariv链接 https://arxiv.org/pdf/2404.10716 效果 Stitched Image 翻译成中文意思是&…...

本地部署DeepSeek-R1模型(新手保姆教程)

背景 最近deepseek太火了&#xff0c;无数的媒体都在报道&#xff0c;很多人争相着想本地部署试验一下。本文就简单教学一下&#xff0c;怎么本地部署。 首先大家要知道&#xff0c;使用deepseek有三种方式&#xff1a; 1.网页端或者是手机app直接使用 2.使用代码调用API …...

神经网络常见激活函数 5-PReLU函数

文章目录 PReLU函数导函数函数和导函数图像优缺点pytorch中的PReLU函数tensorflow 中的PReLU函数 PReLU 参数化修正线性单元:Parametric ReLU 函数导函数 PReLU函数 P R e L U { x x > 0 α x x < 0 ( α 是可训练参数 ) \rm PReLU \left\{ \begin{array}{} x \qua…...

2025我的第二次社招,写在春招之季

先说一个好消息&#xff0c;C那些事 4w star了&#xff01; 前面断更了一个月&#xff0c;本篇文章就可以看到原因&#xff0c;哈哈。 大家好&#xff0c;我叫光城&#xff0c;腾讯实习转正做后端开发&#xff0c;后去小公司做数据库内核&#xff0c;经过这几年的成长与积累&am…...

Visual Studio Code中文出现黄色框子的解决办法

Visual Studio Code中文出现黄色框子的解决办法 一、vsCode中文出现黄色框子-如图二、解决办法 一、vsCode中文出现黄色框子-如图 二、解决办法 点击 “文件”点击 “首选项”点击 “设置” 搜索框直接搜索unicode选择“文本编辑器”&#xff0c;往下滑动&#xff0c;找到“Un…...

threejs开源代码之-旋转的彩色立方体

效果&#xff1a;旋转的彩色立方体 效果描述&#xff1a; 一个立方体在场景中旋转。立方体的每个面有不同的颜色。使用自定义着色器为立方体添加动态的光影效果。 代码实现 import * as THREE from three; import { OrbitControls } from three/examples/jsm/controls/OrbitC…...

visual studio 2008的试用版评估期已结束的解决办法

visual studio 2008试用期过了后&#xff0c;再次启动时提示&#xff1a;visual studio的试用版评估期已结束。 需要的工具&#xff1a;补丁文件PatchVS2008.exe 解决办法&#xff1a; 1.在“控制面板”-“添加删除程序”中选择visual studio 2008&#xff0c;点击“更改/卸载”…...

解锁 DeepSeek 模型高效部署密码:蓝耘平台深度剖析与实战应用

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

Http和Socks的区别?

HTTP 和 SOCKS 的区别 HTTP 和 SOCKS 都是用于网络通信的协议&#xff0c;但它们在工作原理、应用场景和实现方式上有显著的区别。以下是详细的对比和说明。 一、HTTP 协议 1. 定义 HTTP&#xff08;HyperText Transfer Protocol&#xff09;是用于传输超文本数据的应用层协…...

VC播放mp3的方法

1、使用msi库 #include <mmsystem.h> #pragma comment(lib,"winmm.lib") .......//打开文件MCI_OPEN_PARMS mciOpen; mciOpen.lpstrDeviceType _T("mpegvideo"); mciOpen.lpstrElementName _T("c://1.mp3"); MCIERROR mciError mci…...

Docker 部署 verdaccio 搭建 npm 私服

一、镜像获取 # 获取 verdaccio 镜像 docker pull verdaccio/verdaccio 二、修改配置文件 cd /wwwroot/opt/docker/verdaccio/conf vim config.yaml config.yaml 配置文件如下&#xff0c;可以根据自己的需要进行修改 # # This is the default configuration file. It all…...

49-拓展(1)

49-拓展&#xff08;1&#xff09; 扩展概述 扩展可以为在当前 package 可见的类型&#xff08;除函数、元组、接口&#xff09;添加新功能。 当不能破坏被扩展类型的封装性&#xff0c;但希望添加额外的功能时&#xff0c;可以使用扩展。 可以添加的功能包括&#xff1a; …...

国产编辑器EverEdit - 在文件中查找和替换

1 在文件中查找和替换 1.1 应用场景 某些场景&#xff0c;用户需要在所有工程文件中进行查找和替换关键词&#xff0c;比如&#xff1a;查找工程中哪些文件使用了某个常量。 1.2 使用方法 选择主菜单查找 -> 在文件中查找和替换&#xff0c;或使用快捷键Ctrl Shift F&a…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...