poj1011木棒 dfs

来源:互联网 发布:奇迹曼特 知乎 编辑:程序博客网 时间:2024/05/21 08:54
木棒
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 143464 Accepted: 33889

Description

乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。

Input

输入包含多组数据,每组数据包括两行。第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。第二行是截断以后,所得到的各节木棍的长度。在最后一组数据之后,是一个零。

Output

为每组数据,分别输出原始木棒的可能最小长度,每组数据占一行。

Sample Input

95 2 1 5 2 1 5 2 141 2 3 40

Sample Output

6

5

//dfs+剪枝,有两层搜索的过程//可以加入,就加入,如果错误就回溯,又是连续的,就少了个dfs不加的情况 #include<iostream>#include<cstring>#include<algorithm>bool cmp(int b,int c){return b>c;}using namespace std;int vis[100],n,a[100],s,tt,num;bool dfs(int ss,int len,int pos){//ss为当前的和,len为当前达到目标长度的个数,pos为当前的位置if(len==num) return true;for(int i=pos;i<n;i++)if(!vis[i])//下面是关键部分,如果相等,开始另一个搜索,其他的一种搜索,收获多多啊 if(ss+a[i]==tt){vis[i]=1;if(dfs(0,len+1,0)) return true;vis[i]=0;return false;//代表当前的状态要回溯 }elseif(ss+a[i]<tt){vis[i]=1;if(dfs(ss+a[i],len,i)) return true;vis[i]=0;if(ss==0) return false;//一个剪枝while(i+1<n&&a[i]==a[i+1]) i++; //一个剪枝}return false;}int main(){ios::sync_with_stdio(false);cin.tie(0);while(cin>>n&&n){s=0;for(int i=0;i<n;i++){cin>>a[i];s+=a[i];}sort(a,a+n,cmp);for(tt=a[0];tt<=s;tt++)if(s%tt==0)if(num=s/tt,memset(vis,0,sizeof(vis)),dfs(0,0,0)){cout<<tt<<endl;break;}}return 0;}/*915 3 2 11 4 1 8 8 8*/


1 0
原创粉丝点击