本文主要是介绍poj 1011 回溯+剪枝 木棒问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
【题意】:乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。
1.把所有木棍的长度从大到小排列,组合木棒时优先使用长的木棍,这样可以加快组合速度,并且对后面的剪枝有帮助。
2.木棒的长度一定是大于等于最长木棍的长度并且小于等于所有木棍长度的和,这个很容易证明。
3.木棒的长度一定是所有木棍长度的和的约数,这个也很容易证明。
4.在某一个木棒的组合过程中,对于当前的木棍stick[i],如果stick[i-1]没有被组合并且stick[i] == stick[i-1],那么不用考虑stick[i],显然stick[i]最终也不会被组合。
5.如果此次是在尝试第i个木棒的第一段,假设stick[j]为当前可以被使用的最长的木棍,如果此次组合失败,直接退出搜索,即退回到对第i-1个木棒的搜索。试想:失败说明现在使用stick[j]是不可行的,那么以后无论什么时候使用stick[j]都是不可行的,因为以后再处理stick[j]时可使用的木棍一定是当前可使用的木棍的子集,在更多木棍选择的情况下都不能组合成功,那么,在更少木棍选择的情况下一定不能组合成功。
- #include <iostream>
- #include <algorithm>
- using namespace std;
- int sticks[64], n, len, num;
- bool used[64];
- bool compare(int a, int b)
- {
- return a > b;
- }
- bool dfs(int cur, int left, int level)
- { //cur: 当前已经计算的木棒编号,left:该段还剩的长度,level:已经成功的木棒数
- if(left == 0) {//匹配一根木棒成功
- if(level == num-2)
- return true;
- for(cur = 0; used[cur]; cur++)
- ;
- used[cur] = true;
- if(dfs(cur+1, len-sticks[cur], level+1))
- return true;
- used[cur] = false;
- return false;
- } else {
- if(cur >= n-1)
- return false;
- for(int i = cur; i < n; i++) {
- if(used[i])
- continue;
- if((sticks[i] == sticks[i-1]) && !used[i-1])
- continue;
- if(sticks[i] > left)
- continue;
- used[i] = true;
- if(dfs(i, left-sticks[i], level))
- return true;
- used[i] = false;
- }
- return false;
- }
- }
- int main()
- {
- while(cin>>n) {
- if(n == 0)
- break;
- int sum = 0;
- for(int i = 0; i < n; i++) {
- scanf("%d", &sticks[i]);
- sum += sticks[i];
- }
- sort(sticks, sticks+n, compare); //由大到小排序
- bool end = false;
- for(len = sticks[0]; len <= sum/2; len++) {
- if(sum%len == 0) {
- used[0] = true;
- num = sum/len;
- if(dfs(0, len-sticks[0], 0)) {
- end = true;
- printf("%d\n", len);
- break;
- }
- used[0] = false;
- }
- }
- if(!end)
- printf("%d\n", sum);
- memset(used, 0, sizeof(used));
- }
- //system("pause");
- return 0;
- }
http://www.cppblog.com/y346491470/articles/155318.html
http://blog.csdn.net/lyy289065406/article/details/6647960
这篇关于poj 1011 回溯+剪枝 木棒问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!