poj 1011 sticks 搜索加剪枝
2010-10-25 16:10
316 查看
题目描述:
木棒
Description
乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。
Input
输入包含多组数据,每组数据包括两行。第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。第二行是截断以后,所得到的各节木棍的长度。在最后一组数据之后,是一个零。
Output
为每组数据,分别输出原始木棒的可能最小长度,每组数据占一行。
Sample Input
Sample Output
木棒
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 75149 | Accepted: 16564 |
乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。
Input
输入包含多组数据,每组数据包括两行。第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。第二行是截断以后,所得到的各节木棍的长度。在最后一组数据之后,是一个零。
Output
为每组数据,分别输出原始木棒的可能最小长度,每组数据占一行。
Sample Input
9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0
Sample Output
6 5
此题我不会做,所以把别人的解体思路给记录下来,方便自己以后用的时候看.
用dfs,然后在一下这几个方面剪枝:
1. 搜索顺序。首先依据小棒长度进行由大到小的排序,在每一层搜索时首先将长度大的小棒填入当前原棒
中。
因为当相对长的小棒占据了原棒的大部分空间后能大大减小可行的搜索状态。
2. 利用排序剪枝。在组合同一支原棒的时候,由于检验小棒是否可用的顺序也是由大到小的,因此在检验
到一支小棒可用时,如果当前棒还合填满,可能填入当前棒的 小棒的长度也不会比现在填入的这支小棒长。
因此,增加一个递归参数NEXT表示可能用于组合当前棒的第一支小棒的数组下标。参数传递时,若当前正好
拼成一 支原棒,NEXT还原回1,否则将NEXT+1传递给下一层递归。
3. 不进行重复搜索。
别人 0ms ac的代码:#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) { 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() { freopen("in.txt","r",stdin); while(scanf("%d",&n),n) { 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)); } return 0; }
相关文章推荐
- *搜索(剪剪剪枝)POJ - 1011 Sticks
- POJ 1011 STICKS 搜索 剪枝
- 【DFS迭代加深搜索+剪枝】POJ_1011_Sticks
- poj 1011 Sticks 深度搜索+(剪枝)
- poj 1011 Sticks(经典搜索问题:DFS+剪枝)
- poj 1011 Sticks解题报告【DFS+剪枝】
- poj 1011 sticks(木棒) (dfs+剪枝)
- POJ 1011 Sticks (DFS + 剪枝)
- hdu1455 && poj1011 Sticks(深度优先搜索 DFS 经典剪枝 详解)
- POJ 1011 sticks 搜索
- POJ - 1011 - Sticks (DFS + 剪枝)
- POJ-1011-经典搜索题(深搜+剪枝)
- poj 1011 Sticks (DFS+剪枝)
- POJ - 1011 搜索剪枝
- POJ 1011 Sticks(DFS + 剪枝)
- Poj_1011_Sticks(剪枝)
- POJ-1011-Sticks-DFS(深搜)+四次剪枝
- POJ 1011 Sticks 深搜+剪枝
- poj1011——剪枝dfs搜索题
- pku 1011 sticks 搜索+剪枝 解题报告