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

浙公网安备 33010602011771号