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; }