小木棍
乔治拿来一组等长的木棒,将它们随机地裁断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。
请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。
【输入格式】
第一行是一个整数N,表示砍断之后共有多少节木棍。
第二行是截断以后,所得到的各节木棍的长度。在最后一组数据之后,是一个零。
【输出格式】
输出原始木棒的可能最小长度。
【输入样例】
9
5 2 1 5 2 1 5 2 1
【输出样例】
6
【数据范围】
N<=64
每节裁断后的小木棍长度不超过50。
很明显,如果纯暴力枚举拼成的大木棍len(tot%len==0)后,枚举分成的k堆包含哪些棍子(状态函数:bool run(int i,int rest,int p)表示第i堆还差rest的长度到len,第i堆中刚才选了第p根)需要O(x*n!)的时间。。。好像慢得不止一点。
所以优化剪枝很必要。
大概的思路有:
1.减少搜索步骤(如n个状态搜索到n-1层并计算第i层);
2.加强每一步的约束条件;
3.预测性剪枝(最重要的剪枝)
本题大概有四种剪枝思路:
1.将小木棍从大到小排序:我们发现如果小段的木棍先进“队”的话回溯的层次将会比大段的木棍先进多得多。(大段的木棍约束性会更强些)。
*2.