ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

sticks

2020-03-03 16:02:59  阅读:358  来源: 互联网

标签:sticks 木棒 len int length 木棍 长度


# 题意
一组长度相等的木棒,把他们随机砍断,使得每一节木棍的长度不超过50个单位,恢复到剪前的状态,不知道开始有多少根以及他们的长度,计算木棒可能的最小长度

# 题解
因为木棒是等长的所以最开始木棒的长度一定是所有木棒长度和约数,并且原始木棒的根数就等于sum/len

参数中所包含的状态应该有
1)已经拼好的原始木棒的数量
2)正在拼的原始木棒的当前长度
3)每个木棒的使用情况,即上一根拼接上的小木棍

剪枝:
1)优化搜索顺序 小木棍长度从大到小去枚举可以减少搜索树的分支
2)排除等效冗余
1. 限制先后加入一根原始木棒的长度是递减的。先拼上一根长度为x的木棍,再拼上一根长为y的木棍,与先y后x是等价的
2. 对于当前拼的大木棒,记录最近一次尝试拼的小木棒长度,如果这个不可以,就不再想改木棒中拼接其他和这个木棒长度相等的木棒
3. 如果在当前的大木棒中,尝试加入的第一个小木棍失败了,那么这个木棍加到第一个就不可行因为后面的都是没有拼的,空木棒是等价的
4. 如果当前小木棍拼上最后一根后,后面的递归搜索是失败的,那么这个搜索一定是失败的,因为用其他更小的木棒拼起来长度和他相等可以看作是和这个长度较长的是等价的,并且用1根肯定比用多根更优
剪枝的四个性质:
1) 同一根大木棒上面小木棒顺序的等效性
2) 等长木棍的等效性
3) 空木棒的等效性
4) 贪心

#include <bits/stdc++.h>
using namespace std;
const int N=70;
int n;
int len[N];
int sum,length;
bool st[N];

bool dfs(int u,int le,int now){
   //分别表示大木棒的个数、当前正在拼接的木棒的长度,上一个点操作完成后应该操作的下一个点
   if(u*length == sum)     return 1;

   if(le == length) return dfs(u+1,0,0);

   for(int i=now;i<n;i++){
      if(st[i]) continue;

      int l=len[i];
      //加入到当前大棒的过程
      if(le+l<= length) {
         st[i]=1;
         if(dfs(u,le+l,i+1)) return 1;
         st[i]=0;

      //已经回溯,也就是从当前开始的分支失败
      
      //剪枝2,如果是第一根木棍,直接回溯
         if(!le) return 0;
      //剪枝3,如果是最后一根木棍,直接回溯
         if(le+l==length) return 0;
      //剪枝4,不去搜索和当前已经失败长度相等的小木棍
         int j=i;
         while(j<n && len[j]==l) j++;
         i=j-1;
      }
   }
   return 0;
}
int main(){
   while(cin>>n,n){
      sum=0,length=0;
      memset(st,0,sizeof st);

      for(int i=0;i<n;i++) {
         cin >> len[i];
         if(len[i]>50) continue;
         sum+=len[i];
         length=max(length,len[i]);
      }
      //剪枝1,优化搜索顺序,从大到小
      sort(len,len+n);
      reverse(len,len+n);

      for(int i=0;i<n;i++)
         if(len[i]>50)
            st[i]=1;

      while(1){
         if(sum % length==0 && dfs(0,0,0)){
            cout<<length<<endl;
            break;
         }
         length++;
      }
   }
   return 0;
}

 

标签:sticks,木棒,len,int,length,木棍,长度
来源: https://www.cnblogs.com/hhyx/p/12402778.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有