POJ 1011 Sticks (backtrakcing+剪枝)

POJ  1011  Sticks    backtrakcing+剪枝


#include <iostream>
#include <vector>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

int n,sum,maxx,marked,visited[100],ans;
vector <int> v;

void initial(){
	v.clear();
	sum=0;maxx=0;marked=0;
	for(int i=0;i<100;i++) visited[i]=-1;
}

bool cmp(int a,int b){
	return a>b;
} 

void input(){
	int x;
	for(int i=0;i<n;i++){
		scanf("%d",&x);
		v.push_back(x);
		sum+=x;
		maxx=max(maxx,x);
	}
	sort(v.begin(),v.end(),cmp);
}

bool dfs(int cnt,int x,int pos){
	if(cnt==0) return true;
	else if(x==0) return dfs(cnt-1,ans,-1);
	else{
		for(int i=pos+1;i<v.size();i++){
			if(x>=v[i] && visited[i]!=marked){
				visited[i]=marked;
				if( dfs(cnt,x-v[i],i) ) return true;
				else{
					visited[i]=marked-1;
					if( v[i]==x || x==ans) return false;//剪枝的核心
				} 
			}
		}
		return false;
	}	
}

void computing(){
	for(int i=maxx;i<=sum/2;i++){
		if(sum%i==0){
			marked++;ans=i;
			if(dfs(sum/i,i,-1)){
				cout<<ans<<endl;
				return;
			}
		}
	}
	cout<<sum<<endl; 
}

int main(){
	while(scanf("%d",&n)!=EOF && n){
		initial();
		input();
		computing();
	}
	return 0;
}


posted @ 2013-08-21 15:33  炒饭君  阅读(125)  评论(0编辑  收藏  举报