hdu 1455(Sticks 经典深搜)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1455

Sticks

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6193    Accepted Submission(s): 1767


Problem Description
George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.
 

Input
The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.
 

Output
The output file contains the smallest possible length of original sticks, one per line.
 

Sample Input
 
   
9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0
 

Sample Output
 
   
6 5
 

Source
ACM暑期集训队练习赛(七)  
题意:  原来有若干根长度相同的木棍,现在将这若干根木棍剪成n根(题中给出)木棍,长度题中会给出,现在要求原来的若干木棍最短的长度可能是多少?

思路:(1)题意从另一个角度可以这样理解,现有的n个有各自长度的木棍怎么组合拼接成k个木棍,使得k根木棍的长度相同。。那么肯定有很多种组合方法,现在要找到k根木棍长度最小的那种方法;

            (2)经典深搜:将这n根木棍长度从大到小排序,并且求出n根木棍的总长度sum,  那么再想:最小值minn的范围肯定是在stick[0].lenth~sum之间,对吧/ ///,如果sum%minn==0(stick[0].lenth<=min<=sum)

说明i有可能成为最小值,接下来就是具体确定怎么拼接成长度为minn的若干个木棍;

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

int n,cnt,sum;//设置全局变量,n表示木棍的数量,sum表示n个木棍的总长度,cnt=sum/i;

struct node
{
  int lenth // 木棍的长度
  int mark; //标记这根木棍是否被用过;
}stick[66];

int cmp(node a,node b) //按长度从大到小排序
{
    return a.lenth>b.lenth;
}

//len为当前木棒的长度,count统计当前长度木棒的数量,
int dfs(int len,int count,int l,int pos)
{
   if(len==sum) return 1; //递归出口
   if(count==cnt)   return 1;

   for(int i=pos;i(stick[i].lenth+l))
      {
          stick[i].mark=1;
          l+=stick[i].lenth;
          if(dfs(len,count,l,i+1))
             return 1;
          l-=stick[i].lenth;  //如果不能拼接,那么就恢复
          stick[i].mark=0;
          if(l==0) return 0;
          while(stick[i].lenth==stick[i+1].lenth)i++;  //如果不剪支跑一遍要140MS,加上剪支跑一遍只要31MS,ORZ
      }
   }
  return 0;
}

int main()
{
        while(cin>>n&&n)
        {
           cnt=sum=0;
           for(int i=0;i>stick[i].lenth;
               sum+=stick[i].lenth;
               stick[i].mark=0;
           }
           sort(stick,stick+n,cmp);
           for(int i=stick[0].lenth;i<=sum;i++)
           {
              if(sum%i)continue;
              cnt=sum/i;  
              if(dfs(i,0,0,0))
              {
                 printf("%d\n",i);
                 break;
              }
           }

        }
        return 0;
}


你可能感兴趣的:(DFS)