zoukankan      html  css  js  c++  java
  • 看似不是dfs的dfs HDU-1455

    Sticks

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


    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
     
    题意:原本有一些等长的棍子,棍子数量未知。这些棍子被切成任意段,每段长度50以内。输入被切后棍子的数量和长度,要求出的是未被切时的棍子长度。
     
    思路:这题一开始准备用暴力做的,但想着想着感觉跟深搜类似,就尝试用深搜来写了。题目给的数据一定是会使所有木棍凑的出来原来的木棍的,所以就将原来的木棍长度从1开始到所有木棍长度和开始试。将所有木棍从大到小排序,从较长木棍开始选取,到了预定长度就继续选下一个组合成预定长度的木棍组合,如果最后能够将所有木棍成功地组合成预定的长度,这个长度就是最小长度。
    重点:剪枝(不进行剪枝的话绝对会超时,剪枝不完全也会超时,亲身经历/(ㄒoㄒ)/~~)
     
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,sum_len,g_num,g_len;//所有木棍总长度,目标木棍数量,目标木棍长度
     4 int glen[70],vis[70];
     5 bool cmp(int a,int b)
     6 {
     7     return a>b;
     8 }
     9 int dfs(int cnt,int len,int pos)
    10 {
    11     if(cnt == g_num) return true;//木棍数量已经搜索到目标木棍数量
    12     if(len == g_len) return dfs(cnt+1,0,0);//木棍长度等于目标木棍长度,目标木棍数量增加1,开始找下一木棒组合成目标木棒长度
    13     for(int i=pos;i<n;i++)//从已经搜索到的木棒向后挑,向前挑长度大于已搜索的,直接不用向前
    14     {
    15         if(!vis[i]&&len+glen[i]<=g_len)//第i根木棒可以增加且没有被选
    16         {
    17             vis[i]=1;
    18             if(dfs(cnt,len+glen[i],i+1)) return true;//增加后继续搜索
    19             vis[i]=0;
    20             if(len==0) return false;//剪枝!!!这步省去大量时间,将长度小于最大木棍长度的情况直接舍去
    21             while(i+1<n&&glen[i+1]==glen[i]) i++;//后面跟前面长度一样,且前面失败了,直接跳
    22         }
    23     }
    24     return false;
    25 }
    26 int main()
    27 {
    28     while(cin>>n)
    29     {
    30         if(n==0)
    31             break;
    32         sum_len=0;
    33         int glong=0;
    34         for(int i=0;i<n;i++)
    35         {
    36             cin>>glen[i];
    37             sum_len+=glen[i];
    38         }
    39         for(int i=1;i<=sum_len;i++)
    40         {
    41             if(sum_len%i==0)
    42             {
    43                 memset(vis,0,sizeof(vis));
    44                 g_len=i;g_num=sum_len/i;
    45                 if(dfs(0,0,0))
    46                     {
    47                         glong=g_len;
    48                         break;
    49                     }
    50             }
    51         }
    52         cout<<glong<<endl;
    53     }
    54     return 0;
    55 }
    View Code

    这个dfs感觉思路跟暴力差不多,如果各位大大能够有更好点的方法,请各位大大不吝赐教O(∩_∩)O!

     
  • 相关阅读:
    写了一个抓飞信包的小工具
    Drools.Net Bug?
    论坛系统分析比较
    在线个人财务管理服务推荐:财客在线网络账本
    多站点的google analytics的使用心得
    FeedSky更新出现很大延时
    愚人节,中华民族的伟大梦想实现了
    Community Server 2008.5 SP2发布啦
    [已上传流程图]在线服务器状态监控预警软件推荐:网站保姆
    五一公司搬家记
  • 原文地址:https://www.cnblogs.com/forever-snow/p/7140390.html
Copyright © 2011-2022 走看看