【POJ1011】Sticks-DFS+调整法剪枝
来源:互联网 发布:cs1.5优化教程视频 编辑:程序博客网 时间:2024/04/30 15:52
测试地址:Sticks
题目大意:有n根小棍,要拼成若干根长度相等的大棍,问大棍的最小长度是多少。
做法:很容易确定搜索思路:枚举大棍的长度,然后进行DFS查看是否可行,用一个bool函数dfs(r,l)表示当前剩余r根小棍未使用,当前大棍剩余长度为l的情况下是否有解。但是单纯这样裸搜,不知道要搜多少年呢...于是在看了一些资料之后,找到了一些剪枝思路:
1.如果当前大棍长度不是小棍长度之和的因数,不用考虑(应该是很容易就能想到的剪枝)。
2.大棍长度不会小于最长小棍的长度,并且如果在大棍长度≤小棍长度之和/2的范围中如果无解,则结果就已经可以确定为小棍的长度之和(即将所有小棍拼成一根大棍),所以枚举范围为:最长小棍长度≤大棍长度≤小棍长度之和/2。
3.如果将小棍按长度由大到小排序,搜索的时间会显著减少。
4.在开始拼一根新的大棍时,要选还未被使用的最长的小棍作为最开始的小棍,如果发现以这根小棍开始不能拼成这样的大棍,则直接退回去调整上一根大棍。
5.用used数组来表示小棍使用过与否,如果在从小棍标号从小到大枚举的过程中,发现现在的小棍长度和上一根小棍长度相等,且上一根小棍没被使用,则判定为无解,因为如果有解则一定已经在搜索前一根小棍时就出解了。
6.为预防重复搜索,应记录最近拼接的小棍编号no,只用枚举编号比no大的即可(如果是开始拼接一根新的大棍,参照剪枝4)。
7.如果剩余长度等于当前所枚举的小棍长度,则说明该小棍正好填满这根大棍,但如果继续搜索后返回的结果是无解,则退回枚举上一根小棍。
以下是本人代码:
#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int n,len[65],tot,no,i;bool used[65];bool cmp(int a,int b){ return a>b;}bool dfs(int r,int l){ if (r==0&&l==0) return 1; if (l==0) l=i; int start=1; if (l!=i) start=no+1; //剪枝6 for(int j=start;j<=n;j++) if (!used[j]&&len[j]<=l){ if (j>1&&!used[j-1]&&len[j-1]==len[j]) continue; //剪枝5 used[j]=1;no=j; if (dfs(r-1,l-len[j])) return 1; used[j]=0; if (len[j]==l||l==i) return 0; //剪枝4,7} return 0;}int main(){ while(scanf("%d",&n)&&n) { tot=0;for(i=1;i<=n;i++){ scanf("%d",&len[i]); tot+=len[i];}sort(len+1,len+n+1,cmp); //剪枝3for(i=len[1];i<=tot/2;i++) //剪枝2 if (!(tot%i)) //剪枝1 { memset(used,0,sizeof(used));no=1;if (dfs(n,i)){ printf("%d\n",i); break;} }if (i>tot/2) printf("%d\n",tot); } return 0;}
0 0
- 【POJ1011】Sticks-DFS+调整法剪枝
- POJ1011-Sticks DFS+剪枝
- poj1011 Sticks(dfs+剪枝)
- POJ1011 Sticks DFS+剪枝
- POJ1011 Sticks【DFS+剪枝】
- poj1011 -- Sticks (DFS+剪枝)
- poj1011-Sticks dfs各种剪枝
- hdoj1455 poj1011 nyoj293 Sticks【DFS+剪枝】
- poj1011 Sticks DFS深度优先搜索+剪枝
- poj1011——Sticks(dfs+剪枝)
- POJ1011 Sticks 【剪枝】
- poj1011 Sticks(搜索+剪枝)
- poj1011 Sticks(搜索剪枝)
- poj1011 Sticks---dfs
- poj1011 Sticks DFS+回溯
- 【DFS搜索】poj1011 Sticks
- POJ1011 Sticks(dfs)
- 1poj1011(dfs剪枝)
- 将你的Laravel应用部署到Heroku上
- ListView点击item底部弹出popupWindow删除、修改、取消选择框
- 嵌入式系统学习(三)-S5P4418 芯片存储空间分布说明
- Storage Classes in C++ Programming
- 【C/C++语言】指针常量与常量指针的区别
- 【POJ1011】Sticks-DFS+调整法剪枝
- 【myfocus】一款好用的焦点图轮播插件
- 62.Search in Rotated Sorted Array-搜索旋转排序数组(中等题)
- Android之SQLite数据库
- 开发中乱码问题
- 图
- Android版本下载以及切换之 git使用
- Java之接口
- hihocoder 1384 the book list