POJ 1011 Sticks CODE[VS] 3498 小木棍(DFS+剪枝优化)
2016-09-27 21:14
423 查看
剪枝神题
CODE[VS]3498只不过是一组数据最后没有0而已 =_=
木棒
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 139356 Accepted: 32861
Description
乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过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.前后两根长度相等时,如果前面那根没被使用,也就是由前面那根开始搜索不到正确结果,那么再从这根开始也肯定搜索不出正确结果
3.要拼成一根大棍子还需要的长度L>=当前小棍子长度,才能选用
4.本次的小棍长度刚好填满剩下长度,但是后面的搜索失败,则应该返回上一层
代码如下:
加了剪枝就有些迷了呀QAQ
自己还得慢慢参透这份代码
搜素还得慢慢补 加油吧QAQ
CODE[VS]3498只不过是一组数据最后没有0而已 =_=
木棒
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 139356 Accepted: 32861
Description
乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过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.前后两根长度相等时,如果前面那根没被使用,也就是由前面那根开始搜索不到正确结果,那么再从这根开始也肯定搜索不出正确结果
3.要拼成一根大棍子还需要的长度L>=当前小棍子长度,才能选用
4.本次的小棍长度刚好填满剩下长度,但是后面的搜索失败,则应该返回上一层
代码如下:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int size=10010; int num[size],n,sum; bool used[size]; int cmp(int x,int y) {return x > y;} //tot 总数,unused没用过得 rml 当前与验证的答案差多少 len 要验证的答案 bool dfs(int tot,int unused,int rml,int len) { if(unused == 0 && rml == 0) return true; //如果剩余木棍为0,剩余长度为0,拼接完成 if(rml == 0) rml = len; //当前拼接木棍剩余长度为0时尝试新的一个原始长度 for(int i = 1;i <= tot; i ++)//从第一个开始找到最好一个 { if(used[i] == true) continue; //用过的不优先考虑 if(num[i] > rml) continue; //如果当前的木棍比当前差的要少 跳走 used[i] = true; if(dfs(tot,unused-1,rml-num[i],len)==true) return true; //如果答案符合要求 used[i] = false; //寻找下一个木棍 if(num[i] == rml || rml == len) break; //如果某个木棍一上来就等于答案差或最好答案差还是等于原长说明没有木棍跟它匹配 } return false; } void init() { memset(num,0,sizeof(num)); memset(used,0,sizeof(used)); sum = 0; } int main() { // while (scanf("%d",&n)) // { scanf("%d",&n); if(n == 0) return 0; init(); for(int i = 1;i <= n;i ++) { scanf("%d",&num[i]); sum += num[i]; } sort(num + 1,num + n + 1,cmp); for(int i = num[1];i <= sum;i ++) { if(sum % i == 0) if(dfs(n,n,0,i) == true) { printf("%d\n",i); break; } } // } return 0; }
加了剪枝就有些迷了呀QAQ
自己还得慢慢参透这份代码
搜素还得慢慢补 加油吧QAQ
相关文章推荐
- 【DFS&&搜索剪枝】CODE[VS] 3498 小木棍
- poj 1011/2362 dfs+剪枝(拼木棍)
- [DFS+剪枝]POJ 1011/HDOJ 1455/HOJ 1049 Sticks
- poj 1011 Sticks 【DFS】+【剪枝】
- poj1011——剪枝dfs搜索题
- Poj1011 Sticks 小木棍dfs搜索
- ACM: 一题DFS(深搜,剪枝) poj 1011
- poj 1011 Sticks解题报告【DFS+剪枝】
- [POJ 1011] Sticks DFS神剪枝
- poj 1011 Sticks (DFS+剪枝)
- hdu1455 && poj1011 Sticks(深度优先搜索 DFS 经典剪枝 详解)
- hdu 1455/poj 1011 Sticks(DFS剪枝神题)
- POJ 1011 Sticks(DFS回溯剪枝)
- poj 1011 dfs剪枝
- POJ 1011 Sticks (dfs + 厉害的剪枝)
- poj 2363 poj 1011 dfs + 剪枝
- POJ 1011 Sticks (DFS +强力剪枝 (经典))
- DFS(剪枝) POJ 1011 Sticks
- POJ - 1011 - Sticks (DFS + 剪枝)
- POJ1011 Sticks【DFS+剪枝】