【Luogu-P1120】 小木棍 [数据加强版]

暴搜 + 毒瘤剪枝。

说说这道花了我三四天才调处来的毒瘤暴搜。

事实证明,该借鉴题解时就要借鉴题解。

不过做完这题之后确实对深搜、优化、剪枝有了更深刻的理解。

题意

n n n 个小木棒的长度,求他们最多能拼成的长度相同木棍的长度。

下文为了区分,把短的(用来拼的)叫做(小)木棒,长的(被拼接成的)叫做木棍。

思路

试试我新的思路写法。

1

二分?dp?贪心?似乎都不是。

最后认命地发现它就是一道朴素的暴搜,但却有毒瘤的剪枝

所以暴搜的大致解法就是:

很明显,我们要先枚举若干根木棍的长度,再拿他来拼接,dfs 判断是否能拼接成功

每次 dfs 就一根根木棒拼接,看最后是否能拼接成 n / l e n n/len n/len 根的木棍。

注意输入的时候忽略掉那些长度比 50 要大的木棒。

2

先说有点东西的主函数。

首先,在输入了木棒的长度之后要对他们从大到小排序。

易知,相比一根短木棒,长木棒拼接起来会更有限制性,即更短的木棒可以和其他有更多种拼接可能。

也可以理解为短木棒比长木棒更加灵活。

所以,我们在拼接时,就要优先选择长木棒,其次才是短木棒(优化 1)


其次,可以发现,木棍的长度是有限制的:

  1. l e n ∣ s u m len | sum lensum(其中 sum 是木棒总长度,len 是当前枚举木棍长度)。

    原因很简单,每根木棍的长度相等(题目条件)。

  2. l e n ≤ s u m 2 len \le \dfrac{sum}{2} len2sum l e n ← s u m len \gets sum lensum

    因为除了拼接成一根长的木棍之外,木棒至少拼接成两根以上的木棍。

综上所述,

我们只需要枚举 len 从 最长木棒长度(最长木棒不能切割,所以木棒必须包含它)

s u m 2 \dfrac{sum}{2} 2sum,每次如果成功拼接,直接输出结束程序,否则最后跳出循环输出 sum(优化 2)。

3

然后说说出场率最高的 dfs。

每次传递三个变量——k、lst、rst,分别表示当前拼接的木棍编号、上一根被拼接的木棒编号,以及拼接完当前木棍还需要的木棒长度。

主要分成 3 个部分。

1

如果拼接成功,

k =

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值