第一次遇到的时候,这个题目完全没思路,看了人家的解题报告才做,,也不行,各种TLE。。也没什么想法。。只能借鉴别人的了。。
看完这个应该可以彻底的理解这个题目的。。:http://apps.hi.baidu.com/share/detail/17119728
下面是我的代码:
#include<iostream>
#include<stdlib.h>
#include <string.h>
using namespace std;
#define N 70
int sticks[N];//用来存放木棒的长度
int used[N];//用来记录木棒是否使用过
int n,cnt,m,len,flag;
int cmp(const void *a,const void *b)
{
return *(int *)b-*(int *)a;
}
void dfs(int pos,int current,int cnt)//pos用来记录当前sticks[]数组中比较到哪个地方了,current用来记录当前匹配的木棒的长度,cnt记录以匹配的木棒的数量
{
if(cnt==m)
flag=true;//如果以当前的长度能正好匹配完所有的木棒的时候则返回,完成任务,当前长度就是要匹配的最小长度
else if(current==len)//如果current正好等于len,则完成一次匹配,cnt+1;
dfs(0,0,cnt+1);
else
{
int pre=-1;//记录前一个搜索过的值,此次匹配过程中已经搜索过的数值,相同长度就的就不必再匹配
for(int i=pos;i<n;i++)
{
if(!used[i]&&sticks[i]!=pre&¤t+sticks[i]<=len)//很重要的剪枝条件,不容忽略,剪枝的技巧和艺术
{
used[i]=1;
pre=sticks[i];
dfs(pos+1,current+sticks[i],cnt);
used[i]=0;//此次搜索不成功,恢复使用标志
if(pos==0||flag)//只有一根木棒或者已经搜索成功时返回
return ;
}
}
}
}
int main()
{
while(cin>>n&&n>0)
{
int sum=0;
for(int i=0;i<n;i++)
{
cin>>sticks[i];
sum+=sticks[i];
}
memset(used,0,sizeof(used));
qsort(sticks,n,sizeof(sticks[0]),cmp);//木棒长度按照从大到小的长度排序,按照题目的意思,原始木棒的最小长度至少是被截断后最长的木棒的长度,最大是被截后所有木棒的长度和
flag=false;//标志是否成功
for(len=sticks[0];len<=sum;len++)//从原始木棒可能的长度逐一搜索,一旦成功就停止循环,得到的就是最小的
{
if(sum%len==0)//一个很重要的剪枝条件,不容忽略,可以很大的提高效率
{
m=sum/len;
dfs(0,0,0);
if(flag)
break;
}
}
cout<<len<<endl;
}
return 0;
}