POJ 1011
在民国某年,少林寺被军阀炮轰,这些棍子被炸成 N 节长度各异的小木棒
战火过后,少林方丈想要用这些木棒拼回原来的棍子
可他记不得原来到底有几根棍子了,只知道古人比较矮,且为了携带方便,棍子一定比较短
他想知道这些棍子最短可能有多短
分析
·
·
尝试 (枚举) 什么?
枚举所有可能的棍子长度
从最长的那根木棒的长度一直枚举到木棒长度总和的一半
对每个假设的棍子长度,试试看能否拼齐若干根棍子
·
·
真的要每个长度都试吗?
对于不是木棒总长度的因子的长度,可以直接否定,不需尝试
·
·
假设了一个棍子长度的前提下,如何尝试去拼成若干根该长度的棍子?
一根一根地拼棍子
如果拼好前i根棍子,结果发现第i+1根无论如何拼不成了
→推翻第i根的拼法,重拼第i根…..
直至有可能推翻第1根棍子的拼法
·
·
本题真正应该设置的状态是什么
状态可以是一个二元组 (R, M)
R : 还没被用掉的木棒数目
M : 当前正在拼的棍子还缺少的长度
初始状态和搜索的终止状态(解状态)是什么?
假设共有N节木棒,假定的棍子长度是L:
初始状态: (N, L)
终止状态: (0, 0)
·
·
·
剪枝方案
·
·
不要在同一个位置多次尝试相同长度的木棒、
如果某次拼接选择长度为S 的木棒,导致最终失败,则在同一位置尝试下一根木棒时,要跳过所有长度为S 的木棒
·
·
不考虑替换第i根棍子中的第一根木棒(换了也没用)
可以考虑把木棒2, 3换掉重拼棍子i,但是把2, 3都去掉后,换1是没有意义的
因为假设替换后能全部拼成功,那么这被换下来的第一根木棒,必然会出现在以后拼好的某根棍子k中
那么我们原先拼第i根棍子时, 就可以用和棍子k同样的构成法来拼,照这种构成法拼好第i根棍子,继续下去最终也应该能够全部拼成功
这就是一种去重复性的搜索
·
·