hdu 1455(Sticks 고전 심층 검색)

3594 단어 DFS
제목 링크: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
",i); break; } } } return 0; }

좋은 웹페이지 즐겨찾기