UESTC_吴队长征婚 2015 UESTC Training for Search Algorithm & String<Problem E>

E - 吴队长征婚

Time Limit: 10000/4000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

吴队长征婚这件事因为请客而没有传出去(虽然他忘了请一个队吃饭),于是吴队长高兴地玩起了木棒。吴队长拿了一些长度相同的木(guang)棒(gun),随机的把它们截成了N段,每一段最长50。现在他想把这些木棒还原成原来的状态,但是他忘记了原来的木棒有多少根,也忘记了每一根有多长。请帮助他设计一个程序,帮他计算之前木棒可能的最小长度。输入数据保证每一段木棒长度都大于0。

Input

输入有多组数据,每组数据分为两行。
第一行一个整数N,表示截断之后木棒的个数。1N64
第二行N个整数,表示截断之后的每一段小木棒的长度。 当N=0时,表示输入结束。

Output

每组数据输出一个整数占一行,表示原木棒可能的最小长度。

Sample input and output

Sample InputSample Output
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
6
5

解题报告:

 先对木棒进行降序排序

 我们设计几个剪枝:

 1.每截木棒肯定是和的约数

 2.若正在拼某截的第一段,而此时最大的木棒用不上,直接回溯

 3.若拼完某截木棍后,剩下的无法拼成,直接回溯

 4.若该木棍用不上,之后所有长度相同的木棍也用不上

 

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
int tn,tlen,len[100],n;
bool use[100];


bool cmp(int x,int y)
{
 return x > y;
}


bool dfs(int cur,int res,int pos)
{
  if (res == tlen)
   {
        res = 0;
        pos = 0;
        cur ++;
   }
  if (cur == tn)
   return true;
  for(int i = pos;i < n ; ++ i)
   if (!use[i] && res + len[i] <= tlen)
    {   
         use[i] = true;
         if (res + len[i] == tlen)
          {
               if (!dfs(cur+1,0,0))
                {
                     use[i] = false;
                     return false;
                }
             return true;
            }
         else
          {
              if (dfs(cur,res+len[i],i+1))
               return true;
               use[i] = false;
               if (res == 0)
                return false;
               for(int j = i + 1; j < n ; ++ j)
                if(len[i] == len[j])
                 i++;
          }
    }
  return false;
}

int main(int argc , char * argv[])
{ 
 while(scanf("%d",&n) && n)
  {
      int sum = 0;
    for(int i = 0 ; i < n ; ++ i)
     {
         scanf("%d",&len[i]);
         sum += len[i];
     }    
    memset(use,false,sizeof(use)); 
    sort(len,len+n,cmp);
    int ok = 0;
    for(int i = len[0] ; i <= sum / 2 ; ++ i)    
     if (sum % i == 0)
      {
          tn = sum / i;
          tlen = i;
          if(dfs(0,0,0))
            {
              cout << i << endl;
              ok = 1;
              break;
           }
        }
    if(!ok)
     cout << sum << endl;
  }
 return 0;    
}
No Pain , No Gain.
原文地址:https://www.cnblogs.com/Xiper/p/4497071.html