AcWing 167. 木棒 题解(搜索—DFS剪枝)

AcWing 167. 木棒
DFS剪枝,具体过程看代码内部,另外排序也算剪枝的一部分

#include

using namespace std;

const int N = 70;

int n;
int sum;
int len;
int w[N];
bool st[N];

bool dfs(int t, int l, int start){  //分别表示第t根大棍,当前大棍长度为l,从第start根小棍开始算 
	if(t * len == sum) return true;
	if(l == len) return dfs(t + 1, 0, 0);
	
	for(int i = start; i < n; i ++ ){
		if(st[i] || l + w[i] > len) continue;
		
		st[i] = true;
		if(dfs(t, l + w[i], start + 1)) return true;
		st[i] = false;  //到这里表明这小棍不能用
		
		//截至目前已经表明这根小棍没法得到正确答案,以下都是剪枝 
		//剪枝操作
		//1.
		//如果l == 0表示当前大棍的长度长度无法得到正确答案,就剪枝
		//如果l + w[i] == len表示当前大棍的长度无法得到正确答案,就剪枝 
		if(!l || l + w[i] == len) return false; 
		
		//2.如果当前w[i]不合适,那么所有和w[i]等长的小棍都不合适,全部跳过 
		int j = i;
		while(j < n && w[i] == w[j]) j ++ ;
		i = j - 1;
	}
	return false;
}

int main()
{
	while(cin>>n){
		if(!n) break;
		memset(st, 0, sizeof st);
		sum = 0;
		
		for(int i = 0; i < n ; i ++ ){
			cin>>w[i];
			sum += w[i];
		}
		//剪枝操作,大的木棍放前面可以减少搜索的情况 
		sort(w, w + n);
		reverse(w, w + n);
		
		len = 1;
		while(true){
			if(sum % len == 0 && dfs(0, 0, 0)){
				cout<<len<<endl;
				break;
			}
			else len ++ ;
		}
	}
	return 0;
}

你可能感兴趣的:(搜索,深度优先,剪枝,算法)