题意:给出一定数量的小木棒的长度,它是由等长的若干木棒随意砍断所得到的。对于给定的一组小木棒,请求出原始木棒的最小长度。
经典搜索题,注意搜索中的剪枝,否则会超时。
#include <iostream>
#include<algorithm>
#include<functional>
using namespace std;
int n;
int stick[100];
bool isChoose[100];
bool search(int totallength,int curlength,int used)
{
if(used==n && curlength==totallength) return true;
if(curlength==totallength) curlength=0;
if(curlength+stick[n-1]>totallength) return false; //没什么效果
for(int i=0;i<n;i++)
{
if(isChoose[i]) continue;
if(curlength+stick[i]>totallength) continue;
isChoose[i]=1;
if(search(totallength,curlength+stick[i],used+1))
return true;
isChoose[i]=0;
if(curlength+stick[i]==totallength || curlength == 0) /*第一个条件对应当前木棒刚好能组成一根大木棒,第二个条件对应当前木棒是组合开始时的第一个木棒。*/
break;
}
return false;
}
int main()
{
while(true)
{
cin>>n;
if(n==0 ) break;
int sum=0;
for(int i=0;i<n;i++)
{
cin>>stick[i];
sum+=stick[i];
}
memset(isChoose,0,sizeof(isChoose));
sort(stick,stick+n,greater<int>());
for(int i=n;i>=1;i--) //这里从木棒的数目遍历比从木棒的长度遍历的次数要少
{
if( sum%i==0 && sum/i>=stick[0])
if(search(sum/i,0,0))
{
cout<<sum/i<<endl;
break;
}
}
}
return 0;
}