Sticks
作者:互联网
题意:给你一组等长木棒,然后他随意砍断成n个木棒,木棒长度不一,但你知道分别是多少,要你求出原始木棒可能的最小长度。
思路:首先那个原始木棒的长度肯定是其总长度的约数,然后也肯定大于等于所有木棒的最大值,然后去DFS,要注意的是,DFS的过程中我肯定先从大的取起,这样可以优化搜索顺序,然后还记录最近一次尝试拼接失败的木棍,减少冗余。
坑点:数据有大于50的要忽略,就是这样。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<map> #include<vector> #include<queue> #include<cmath> using namespace std; int a[100],v[100],n,len,cnt,true_n; bool dfs(int stick,int cab,int last) { if(stick>cnt) return true; if(cab==len) return dfs(stick+1,0,1); int fail=0; for(int i=last;i<=n;i++) { if(!v[i]&&cab+a[i]<=len&&fail!=a[i]) { v[i]=1; if(dfs(stick,cab+a[i],i+1)) { return true; } fail=a[i]; v[i]=0; if(cab==0||cab+a[i]==len) return false; } } return false; } int main() { while(~scanf("%d",&n)) { if(n==0) break; int sum=0; int ma=0; true_n=0; for(int i=1;i<=n;i++) { int x; scanf("%d",&x); if(x>50) continue; true_n++; a[true_n]=x; sum+=a[true_n]; ma=max(ma,a[true_n]); } sort(a+1,a+1+true_n); reverse(a+1,a+true_n+1); for(len=ma;len<=sum;len++) { if(sum%len) continue; cnt=sum/len; memset(v,0,sizeof(v)); if(dfs(1,0,1)) break; } printf("%d\n",len); } }
标签:ma,Sticks,int,len,木棒,include,true 来源: https://www.cnblogs.com/2462478392Lee/p/11285065.html