回溯经典剪枝——小木棍
来源:互联网 发布:python base64.decode 编辑:程序博客网 时间:2024/06/05 16:16
小木棍
乔治拿来一组等长的木棒,将它们随机地裁断,使得每一节木棍的长度都不超过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.如果每堆的第一根木棍判断出无解则返回false:因为木棍在不同的堆中都可以作为第一根,所以如果木棍在这一堆中不满足,则到其他堆去同样不满足。
*3.如果放入某堆中的最后一根木棍刚好rest==0但后续不满足则返回false:原因同上。
*4.之后选择的元素!=之前选择的元素:选后效果将会是一样的,返回false还会是返回false。实现时需注意可能当前的元素可能会因为和上一个vis=1(用过)的数相等而被continue,所以这里用一个失败参数记录上一次失败用的元素。
#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>#include<cstring>#include<cctype>#include<vector>#include<map>using namespace std;const int maxn=80;int n,a[maxn],maxv,tot,vis[maxn],k,len;bool cmp(int a,int b){ return a>b;}bool run(int i,int rest,int p)//第i堆还差rest的长度到len,第i堆中刚才选了第p根 { if(i>k)//共k堆 { return 1; } int fail=0; for(int x=p+1;x<=n;x++)//从第p+1根开始选 if(!vis[x]) { if(a[x]==a[fail]) continue;//注意continue和return if(rest>a[x]) { vis[x]=1; bool w=run(i,rest-a[x],x); vis[x]=0; if(!w) fail=x; if(w) return 1; } else if(rest==a[x]) { vis[x]=1; bool w=run(i+1,len,0); vis[x]=0; return w; } if(p==0) return 0; } return 0;}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); maxv=max(maxv,a[i]); tot+=a[i]; } sort(a+1,a+1+n,cmp); for(len=maxv;len<=tot;len++) if(tot%len==0) { k=tot/len; if(run(1,len,0)) { printf("%d",len); break; } } return 0;}
- 回溯经典剪枝——小木棍
- 回溯+剪枝+剪枝+剪枝...... Vijos P1199 小木棍
- 小木棍-搜索剪枝
- 常用剪枝小结与小木棍问题
- 迷宫中回溯法的剪枝——奇偶剪枝
- 迷宫中回溯法的剪枝——奇偶剪枝
- 【DFS&&搜索剪枝】CODE[VS] 3498 小木棍
- 【luogu】【DFS+神剪枝】小木棍(数据加强)
- POJ 2531 dfs回溯(小剪枝)
- 小木棍
- 小木棍
- 小木棍
- 小木棍
- 小木棍
- 经典算法——回溯
- poj1011——木棍
- 迷宫中回溯法的剪枝——奇偶剪枝(hdu 1010 Tempter of the Bone)
- 搜索剪枝回溯经典题目 pku 1011 sticks
- 有时间去看这个博客
- tensorflow tf.placeholder
- 设计模式之原型模式
- Archlinux系统移植
- [BZOJ P1821]部落划分
- 回溯经典剪枝——小木棍
- Codeforces 832D Misha, Grisha and Underground
- iO逆向 触动精灵网络请求
- img等比例缩放
- 浅谈图片压缩方式
- virtualbox 出现1908错误问题 以及正常安装增强包方法
- jQuery 高级事件(模拟操作)不点击(触发)事件触发操作
- iOS逆向之reveal查看app界面
- 一次Java调用OS命令的优化过程实录