小木棍

题目描述

乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050。

现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。

给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。

输入输出格式

输入格式:

共二行。

第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65N65

(管理员注:要把超过5050的长度自觉过滤掉,坑了很多人了!)

第二行为NN个用空个隔开的正整数,表示NN根小木棍的长度。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<vector>
  7 #include<queue>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 using namespace std;
 12 const int maxn=100007;
 13 const int INF=0x7f7f7f7f;
 14 int n,m,sum,stp,ans=INF,req;
 15 int len[maxn],s[maxn],nxt[maxn];
 16 bool is[maxn],usd[maxn],bj; 
 17 void gettable(){
 18   for(int i=2;i<=sqrt(sum);i++){
 19     if(sum%i==0){
 20       if(i>=len[1]) s[++stp]=i;
 21       if(i!=(sum/i)) if(sum/i>=len[1]) s[++stp]=sum/i;
 22     }
 23   }
 24 }
 25 bool cmp(int a,int b){
 26   return a>b;
 27 }
 28 /*bool dfs(int now,int st,int lft){
 29   bool flg=false;
 30   if(lft==0&&st==sum/req) return true;
 31   if(lft==0){
 32     int i;
 33     for(i=1;i<=n;i++){
 34       if(!usd[i]){usd[i]=true;flg=true;break;}
 35     }
 36     if(flg) dfs(i,st+1,req-len[i]);
 37   }
 38   bool flag=false;
 39   for(int i=now+1;i<=n;i++){
 40     if(usd[i]) continue;
 41     if(lft>=len[i]){
 42       usd[i]=true;flag=true;
 43       if(dfs(i,st,lft-len[i])) return true;
 44       else return false;
 45       usd[i]=false;
 46     }
 47   }
 48   if(!flag) return false;
 49 }*/
 50 void dfs(int k,int last,int rest){
 51   int i,j;
 52   if(rest==0){
 53     if(k==(sum/req)){bj=1;return;}
 54     for(i=1;i<=n;i++)
 55       if(!usd[i]){usd[i]=true;break;}
 56     dfs(k+1,i,req-len[i]);
 57     usd[i]=false;
 58     if(bj) return;
 59   }
 60   int l=last+1, r=n, mid;
 61   while(l<=r){
 62     mid=(l+r)/2;
 63     if(len[mid]<=rest) r=mid-1;
 64     else l=mid+1;
 65   }
 66   for(i=l;i<=n;i++){
 67     if(!usd[i]){ 
 68       usd[i]=1;
 69       dfs(k,i,rest-len[i]);
 70       usd[i]=0;
 71       if(bj) return;   
 72       if(rest==len[i]) return; 
 73       i=nxt[i];
 74       if(i==n) return;
 75     }
 76   }
 77 }
 78 int main(){
 79   cin>>m;
 80   for(int i=1;i<=m;i++){
 81     int a;cin>>a;if(a>50) continue;
 82     len[++n]=a;sum+=len[n];
 83   }
 84   sort(len+1,len+n+1,cmp);
 85   gettable();
 86   sort(s+1,s+n+1,cmp);
 87   nxt[n]=n;
 88   for(int i=n-1;i>=1;i--){
 89     if(len[i]==len[i+1]) nxt[i]=nxt[i+1];
 90     else nxt[i]=i;
 91   }
 92   for(int i=1;i<=stp;i++){
 93       if(is[i]) continue;
 94       memset(usd,false,sizeof(usd)); 
 95       bj=false;usd[1]=true;req=s[i];
 96     dfs(1,1,req-len[1]);
 97     if(!bj){
 98       for(int j=i+1;j<=stp;j++){
 99         if(s[i]%s[j]==0) is[j]=true;
100       }
101     }
102     else ans=min(ans,s[i]);  
103   }
104   if(ans==INF) cout<<sum<<endl;
105   else cout<<ans<<endl;
106 } 

猜你喜欢

转载自www.cnblogs.com/lcan/p/9885374.html
今日推荐