题意:给出最多64根短木棍,求其能恢复出相同长度的木棍的情况下最短木棍长度。
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<malloc.h>
using namespace std;
int n,sum,m,cur;
int go[66];
bool vis[66];
bool cmp(int a,int b)
{
return a>b;
}
bool dfs(int p,int res,int left)
{
if (left==cur) return true;
for (int i=p+1;i<n;i++) if (res+go[i]<=cur && !vis[i])
{
vis[i]=true; // 用于记录是否已经被用
if (res+go[i]==cur)
{
if (dfs(-1,0,left-cur)) return true;
}
else if (dfs(i,res+go[i],left)) return true;
vis[i]=false;
if (res+go[i]==cur) return false; // 如果以后根没有凑好,则表示一直会凑不好
if (res==0) return false;
while (go[i+1]==go[i]) i++; //相邻相同长度木棍情况排除
}
return false;
}
int main()
{
freopen("in","r",stdin);
int i,j,k;
while (cin>>n,n)
{
m=sum=0;
for (i=0;i<n;i++) scanf("%d",go+i),sum+=go[i],m=max(m,go[i]);
sort(go,go+n,cmp); // 排序很关键
go[n]=-1;
memset(vis,false,sizeof(vis));
for (cur=m;cur<=sum;cur++) if (!(sum%cur)) // 去除不可能恢复出的单根木棍的长度
{
if (dfs(-1,0,sum)){
printf("%d\n",cur);
break;
}
}
}
}