5.1 小木棍(搜索剪枝)
题目链接
题目思路
dfs的思想需要学习,努力剪枝减小时间复杂度
当第一个木棍尝试dfs无法拼成后,直接break
当最后一个尝试dfs无法拼成后,直接break
a[i]不行的话,等于a[i]的也不行
代码实现
#include<bits/stdc++.h>
using namespace std;
const int Max=100;
int n,nmax,sum,a[Max],vis[Max];
bool cmp(int a,int b)
{
return a>b;
}
bool dfs(int num,int len,int rest,int now)
{
if(num==0&&rest==0) return 1;
if(rest==0&&num!=0)
{
rest=len;
now=1;
}
for(int i=now;i<=n;i++)
{
if(vis[i]||a[i]>rest) continue;
vis[i]=1;
if(dfs(num-1,len,rest-a[i],i)) return 1;
vis[i]=0;
if((a[i]==rest)||(len==rest)) break;
while(a[i]==a[i+1]) i++;
}
return 0;
}
int main()
{
cin>>n;
nmax=sum=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
}
sort(a+1,a+n+1,cmp);
int num=n;
for(int ii=a[1];ii<=sum;ii++)
{
if(sum%ii!=0) continue;
if(dfs(num,ii,ii,1))
{
cout<<ii<<endl;
return 0;
}
}
return 0;
}