作者:
67ovo
,
2022-08-06 15:46:07
,
所有人可见
,
阅读 2
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=70;
int w[N];
bool st[N];
int n,length,sum;
bool dfs(int u,int s,int start)//当前组数,当前组的长度,当前枚举起始位置
{
if(u*length==sum)return true;
if(s==length)return dfs(u+1,0,0);
for(int i=start;i<n;i++)
{
if(st[i])continue;
if(s+w[i]>length)continue;
st[i]=true;
if(dfs(u,s+w[i],i+1))return true;
st[i]=false;
//排除等效冗余
//优化3:如果是大木棒的第一根小木棒就搜索失败了,则一定搜不到方案
if(!s)return false;
//优化4:如果是大木棒的最后一根小木棒搜索失败了,也一定搜不到方案
if(s+w[i]==length)return false;
//优化5:如果当前的棒搜索失败,那后面与它相等的也一定失败
int j=i;
while(j<n&&w[j]==w[i])
{
j++;
}
i=j-1;
}
return false;
}
int main()
{
while(cin>>n,n)
{
sum=0;
for(int i=0;i<n;i++)
{
cin>>w[i];
sum+=w[i];
}
sort(w,w+n);//优化2:优化搜索顺序,从大到小枚举可以减少分支
reverse(w,w+n);
//枚举长度
length=1;
while(1)
{
if(sum%length==0&&dfs(0,0,0))//优化1:不能整除就不可能得到合法方案
{
cout<<length<<endl;
break;
}
length++;
}
memset(st,0,sizeof st);
}
return 0;
}