题目:详见https://www.luogu.org/problemnew/show/P1120
解题思路:深搜其实和枚举类似,但是加上剪枝,能让运算时间大大减小
#include<bits/stdc++.h>
using namespace std;
int cnt,s[100],use[100],ct;
bool cmp(int x,int y)
{
return x>y;
}
void dfs(int sum,int ans,int target,int st)
{
if(ans==0)
{
printf("%d", target);
exit( 0 );
}
if(sum==target)
{
dfs(0,ans-1,target,0);//如果达到预期,就进行下一轮拼接
return;
}
if(s[cnt-1]>target-sum) return;
for(int i=st;i<cnt;i++)
{
if(!use[i]&&s[i]+sum<=target)
{
use[i]=1;
dfs(sum+s[i],ans,target,i+1);
use[i]=0;
if(sum+s[i]==target||sum==0) break;//如果能组成一组却不可行或者有一组行不通直接退出
while(s[i]==s[i+1])i++;//如果是s[i]==s[i+1] ,那么s[i] 没成功,s[i+1]就更不可能成功!
}
}
}
int main()
{
//freopen("t.txt","r",stdin);
int n,t;
scanf("%d",&n);
cnt=0;
int sum=0,ma=-1;
memset(use,0,sizeof(use));
while(n--)
{
scanf("%d",&t);
if(t<=50)
{
s[cnt++]=t;
sum+=t;
if(t>ma) ma=t;
}
}
sort(s,s+cnt,cmp);
for(int i=ma;i<=sum/2;i++)
{
if(sum%i) continue;
dfs(0,sum/i,i,0);
}
printf("%d\n",sum);
return 0;
}