Sticks<DFS>
2016-05-29 21:30
239 查看
题意:
给n个木棍,这些木棍是由m个长度均为L的木棍切割而来,求L的最小值。
思路:
DFS+剪枝。
剪枝:
1:L的取值范围在n(max)和n(sum)之间,逐个枚举。sum%L!=0则L不能用。 2:sort对n个木棍长度进行由小到大排序,有以下好处: a:从大的开始搜索。eg:如果L8;5+3>(优势)5+2+1;把更灵活地木棍留下来。 b:查找更有序。 3:如果有一个木棍无法和其他木棍组合成L,则此种方案不行。<有两种情况>。 4:如果len[i]无法和当前的木棍组成,那么如果len[i+1]=len[i],len[i+1]也不行。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int len[5005],vis[5005]; int n,sum,num,L; int cmp(int a,int b) { return a>b; } int DFS(int m,int S,int N)//m代表当前已经组成的木棍数,S代表当前木棍的长度,N等会 { if(m==num-1)//b:已经有num-1根木棍组合好了,那么剩下的木棍一定也可以组成一根; return 1; for(int i=N;i<n;i++){ if(!vis[i]&&(S+len[i])==L) { vis[i]=1; if(DFS(m+1,0,0)) return 1; vis[i]=0;//虽然上步已经说明这条路行不通,还是要回溯回来原因是下一个else return 0;//C; } if(!vis[i]&&(S+len[i])<L) { vis[i]=1; if(DFS(m,S+len[i],i+1)) return 1; vis[i]=0; if(S==0)//说明剩下的木棍无法组成; return 0;//D; while(len[i]==len[i+1])//E:此路不通,len[i]不行,如果len[i+1]=len[i],len[i+1]也不行。 ++i; } } return 0; } int main() { while(scanf("%d",&n)!=EOF) { if(n==0) break; sum=0; for(int i=0;i<n;i++){ scanf("%d",&len[i]); sum+=len[i]; } sort(len,len+n,cmp); for(L=len[0];L<=sum/2;L++)//a:减少L的枚举数量,如果L>sum/2,那么只能只有一根木棍 { if(sum%L==0)//满足L的条件再递归 { memset(vis,0,sizeof(vis)); num=sum/L; if(DFS(0,0,0)){ printf("%d\n",L); break; } } } if(L>sum/2) printf("%d\n",sum); } return 0; }
相关文章推荐
- Socket实现两台手机通信,定向转发数据
- java compiler level does not match the version of the installed java project facet
- Minimum Size Subarray Sum
- php核心知识点
- 【面试】【MySQL常见问题总结】【02】
- 怎么判断百度网盘分享连接已经失效?其实没那么简单
- MySQL server has gone away 问题的解决方法
- FluentValidation
- 打印二叉树的所有路径
- 7+1道题
- SOCKET API和TCP STATE的对应关系__三次握手(listen,accept,connect)__四次挥手close及TCP延迟确认(调用一次setsockopt函数,设
- Logistic回归
- [NTT 原根 指标 多项式快速幂] BZOJ 3992 [SDOI2015]序列统计
- Android WebKit
- TCP/IP模型 ,Socket编程总结
- ubuntu 下搭建一个python3的虚拟环境(用于django配合postgresql数据库开发)
- git使用
- oracle的启动和关闭
- I/O复用(I/O multiplexing): select, pselect, poll, ppoll, epoll
- 【JAVA笔记——术】Java ClassLoader类加载机制详解