POJ - 1011(dfs回溯+剪枝)

2019 GDUT Winter Training I (dfs/bfs/二分/三分/尺取) H - dfs

专题传送门

poj传送门

题目大意:

大概就是有个人闲着无聊,把不知道多少根等长的木棍砍成短木棍,但忘记了初始时有多少木棍以及木棍的初始长度,现在给你砍完后短木棍的长度,问你初始木棍的可能最小长度。

题目分析:

现在我们应该容易从题目看出下面的隐藏条件 (剪枝)。剪不够就TLE到要哭
1.长木棍的长度大于等于最长的短木棍。
2.短木棍长度之和一定可以整除长木棍的长度。
3.将短木棍从长到短排更容易找到答案,因为在组合的时候长棍子不灵活。
4.如果某个短棍子在一次组合中不满足要求,那么就不需要考虑和它相等长度的棍子了。
5.如果当前最长的一支可用小棒L0恰能填满当前正在组合的一支原棒,则如果此次尝试失败,在当前状态下不再做其它尝试,返回上一层递归。因为若当前状态成功,则当前原棒的剩余长度必定能由另几支更短的小棒L1、L2……Ln组合成,且L0必定出现在之后组合的某支原棒之中,则可以将其中的L0替换为L1、L2……Ln,而将L0移加当前原棒中,则两种状态等价,因此同样必定失败。因此,在stick[i]==len时,若搜索失败,则同样停止当前状态的其它搜索。
6.在一次组合的第一步,如果是组合的第一步,而且没找到合适的组合,那么就可以结束尝试了,因为该棍子迟早要用于一种组合之中的。

这题我们可以用dfs不断尝试原始木棍的长度,直到得到答案。
这里我dfs传递的参数是剩余木棍的总长度,以及当前在组合的棍子的长度,当剩余木棍总长度和当前组合的棍子的长度为0时才能返回true,即组合成功。
还要注意回溯,如果组合失败就回溯,即取消之前棍子的标记。

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值