POJ1011题解(dfs+减枝,好理解一点)
题意:n根不同长度的小棍,拼成若干长棍,要这些长棍的长度相等,并且小棍刚好用完,问拼成长棍的最短长度是?
思路:首先考虑搜索的方向,最短,那肯定是从最短的情况开始递增,最短的可能情况那肯定就是最长的的单个棍子,所以首先把这些小棍排序,从大到小,并计算这些棍子总和,拼成的长棍的长度从最长的小棍开始搜索,搜索的过程也是判断,用总和除以这个长度得到应该拼成的长棍个数,递归搜索判断小棍之间能否相组合成满足这么多个长度相等的长棍。
在搜索过程中 注意四个地方可以剪枝(效果还是很惊人的)
1.搜索的起点是最长的小棍长度,而不用从1开始。
2.用一个used数组标记,哪个小棍用过了。
3.(重要)当一个棍子发现没有棍子可以与他配对,直接跳过,
后面的棍子尝试,这次棍子长度绝对不满足,直接尝试下一个长度。
4.(重要)当一个棍子的长度已经被否定不能与这个棍子配对,避免出现下个
与上个相同的情况,搜索重复,由于排好序的,如果这个和下个相等,
就移到不相等的数字再尝试。
注意:(我自己写题时候的为题)我觉得比较重要的 num++和num+1的区别:/num++运算后num实际取值为num+1,但显示的结果仍未num,下次运算时用num+1的取值运算,但显示num+1的值;num=num+1的值显示和实际的都为num+1.
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int n,sum,num,flag;
int a[65],vis[65];
bool cmp(int x,int y){
return x>y;
}
void dfs(int num1,