poj 1011/2362 dfs+剪枝(拼木棍)

该博客介绍了如何使用深度优先搜索(DFS)结合剪枝策略来解决一个数学问题:恢复被裁剪的木棍。文章讨论了在解决此问题时的关键剪枝点,包括木棍总长度、最大长度、总和的约束,以及两个关键的剪枝策略,强调了排序和特定状态的判断在优化搜索效率中的重要性。还提及了题目的两个变种,1011和2362,并提到了北京大学郭炜老师的另一种解题方法。
摘要由CSDN通过智能技术生成

题意:乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。(2362是1011的特例,问一堆木棍能否拼成正方形)

思路:dfs+剪枝。其中剪枝具有相当的技巧性,其中一个地方的剪枝没有想到导致tle多次。

几个明显的剪枝点(设ans为最终的答案):

1、ans>=这堆木棍的最大长度

2、ans<=这堆木棍长度的总和

3、ans必可以被这堆木棍长度总和整除

4、对木棍由长到短排序,先考虑长的能有效剪枝

两个不明显但是最重要的剪枝点,缺一不可:

5、如果某次刚刚加入长度为x的木棍而随后搜索失败,则接下来的搜索只需搜比x小得木棍即可(代码中pre变量的作用)。

6、在每次构建新的长度为ans的木棍时,检查新棒的第一根s[i],若在搜索完所有木棍后都无法组合,则说明s[i]无法在当前组合方式下组合,不用往下搜索(因为再怎么搜索s[i]都不会加入到任何一个木棍当中)。代码中if(!from) return 0;这句话的作用。

1011:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define max(a,b) ((a)>(b)?(a):(b))
#define N 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值