【搜索 技巧】Letter gaps

本文探讨了一道复杂的字符串构造问题,目标是在限定长度内构建特定模式的字符串,通过逐步优化搜索策略,从暴力搜索到高级搜索技巧,实现了效率的显著提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需要一定技巧的搜索题

题目描述

记得做过这样一道题

Ponder This Challenge:
In the string CABACB, each letter appears exactly twice and the number of characters between the "A"s is one, between the "B"s is two, and between the "C"s is three. The same problem with the letters A-E cannot be solved, but adding a space (in the form of a hyphen) allows it to be solved. For example, in the string ADAEC-DBCEB, the number of characters between the "A"s is one, between the "B"s is two, between the "C"s is three (counting the space), between the "D"s is four, and between the "E"s is five. Find a string of letters (A-Z) and "-" whose length is no more than 53 characters, where each of the 26 letters A-Z appears exactly twice, and there is one character between the "A"s, two between the "B"s ... and 26 between the "Z"s.

现在输入 n26,你需要输出一个对于前 n 个大写字母的长度不超过 2n+1 的解。

空格(space)用连字符(hyphen) - 表示。

数据规模与约定

共 25 个数据,2n26

  时间限制:1s

  空间限制:256MB


题目分析

题目大意

构造有前n个大写字母的字符串:字符串需要满足'A'和'A'之间有一个字符,'B'和'B'之间有两个字符……字符串之中最多允许有一个空格。

 

NPC

显然这是一道NPC问题,那么考虑怎么搜索。

 

搜索一  暴力的暴力搜索

我们使用一个2*n+1长度的a[]数组保存这个字符串;n+1大小的vis[]数组检验第i个字符使用了几次

接下去DFS每一个位置、枚举每一个可以使用的字符。直到我们dfs完了所有字符,再从头检查这个字符是不是合法的。

这种原始方法已经是枚举所有的方案数了,速度可想而知。

1s跑出的答案:2-5个

 

优化一  每次投放两个字符

既然合法的充要条件是两个第i个字母之间相隔i个字符,为什么不在DFS时候这样处理呢?

1s跑出的答案:2-13个

 

优化二  倒着枚举投放字符

由于题目的特殊性质,显然可以发现:如果正着枚举,很容易出现字符之间已经挤得满满当当,却检验不合法,因此此后必须搜索很多无用的状态。

因此我们倒着来。这样可以使每一对已确定下来的字符之间有大量间隔,这样能够更快速地搜索出可行解。

1s跑出的答案:2-16个

 

搜索二  换个角度dfs

即便使用了以上两个优化、即便你卡常技巧再高超,抱歉搜索到n=20左右效率又奇低无比了。

实际上,搜索一所面对的dfs对象决定了效率的低下。这和dp其实很相像,看似差之毫厘的dp方程在效率上却有很大的差别。

考虑一下dfs每一个字母,枚举它可以存在的位置

从写法上看,它要简洁很多。

从效率上看,它的状态数也大大减少。

只考虑所有状态的话大致是上面的这两个表达式。大概就是以下这样的图像。

并且当n增大时,两者的差别还是非常明显的。

 

 

有时候我很奇怪,为什么在动态规划和搜索中,这样的看上去微不足道的改动却足以造成这样大的差别。或许问题归根结底还要靠数学分析,也或许这一方面的一些感觉需要大量的做题积累,不过这倒是一种很好的思路方向。

真的挺不错的一种思路方向。

 

 

 

 

END

 

转载于:https://www.cnblogs.com/antiquality/p/8849186.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值