学习于:https://blog.csdn.net/acmer_hades/article/details/47069245
现在有n根木棍,然后需要把它们拼成同样长度的木棍,问满足这个条件的最短的长度是多少?
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int a[70],n,len,num=0,vis[70];
bool cmp(int a,int b){
return a>b;
}
int dfs(int k,int cur)///
{
if(k==0&&cur==0)return 1;///木棍都已拼完,且剩余长度为0
if(cur==0)cur=len;///k!=0时,如果上一根木棍刚好拼成所需长度,则开始拼新木棍
int cnt=1;///拼新木棍时,从最长的开始遍历,找到第一个没用过的小木棍
if(cur!=len)cnt=num+1;///第一根小木棍已确定,那么第二根的下标在它的后面
int i;
for( i=cnt; i<=n; i++)
{
if(vis[i-1]==0&&i>1&&a[i]==a[i-1])continue;///与上一根长度相同,上一根匹配失败且不是最后一根
if(!vis[i]&&a[i]<=cur)///这根没用过,且长度比剩下需要的长度小
{
vis[i]=1;
num=i;///这根小木棍的下标
if(dfs(k-1,cur-a[i])) return 1;
else{
vis[i]=0;///这根木棍不满足题意,取消标记
if(len==cur||a[i]==cur) return 0;///重新拼凑
}
}
}
return 0;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==0)break;
int sum=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
sort(a+1,a+1+n,cmp);
for(len=a[1]; len<=sum/2; len++) ///单根大于总和一半时,则所有木棍只能组成一根
{
if(sum%len==0)///能被len整除,才有可能符合条件
{
memset(vis,0,sizeof(vis));
if(dfs(n,len))break;
}
}
if(len>sum/2)printf("%d\n",sum);
else printf("%d\n",len);
}
return 0;
}