• 【深度搜索+剪枝】POJ1011-Sticks


    深搜部分和之前的POJ2362差不多,只是有几处需要额外的剪枝。

    【思路】排序后从最短木棒开始搜索至木棒长总和,如果木棒长总和sum能整除当前棒长,则进入深搜。

    【剪枝】先前POJ2362的剪枝部分不再重提,这里只讲额外的几处(我们称切断后的棒为木棒,切断前的棒为原棒):

    1.如果所有木棒等长,即排序后stick[0]=stick[n-1],则直接输出棒长;

    2.如果当前搜索的棒长即是棒长总和,无需进入深搜子程序,直接输出;

    3.如果深搜中当前长度的木棒不能选择,则略去同一层中相同长度的木棒;

    4.如果当前是重新开始组成一个原棒,即len=0时。如果可以组成原棒,则取frm时必然能返回真(因为组成原棒的顺序是无所谓的);若选取frm时仍然无法组成,则说明不能组成原棒,直接退出深搜,返回假。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int MAXN=64+5;
     7 int n,sl;
     8 int stick[MAXN];
     9 int vis[MAXN];
    10 
    11 int dfs(int side,int frm,int len)
    12 {
    13     if (1==side) return 1;
    14     int last=-1;
    15     for (int i=frm;i>=0;i--)
    16         if (!vis[i] && stick[i]!=last)
    17         {
    18             vis[i]=1;
    19             if (sl==len+stick[i])
    20             {
    21                 if (dfs(side-1,n-1,0)) return 1;
    22             }
    23             else  if (sl>len+stick[i])
    24             {
    25                 if (dfs(side,i-1,len+stick[i])) return 1;
    26             }
    27             vis[i]=0;
    28             last=stick[i]; 
    29             if (len==0) break;
    30         }
    31     return 0;
    32 }
    33 
    34 int main()
    35 {
    36     while (scanf("%d",&n))
    37     {
    38         if (0==n) break;
    39         int sum=0;
    40         for (int i=0;i<n;i++) 
    41         {
    42             scanf("%d",&stick[i]);
    43             sum+=stick[i];
    44         }
    45         sort(stick,stick+n);
    46         if (stick[0]==stick[n-1])
    47         {
    48             cout<<stick[0]<<endl;
    49             continue;
    50         }
    51         for (int i=stick[0];i<=sum;i++)//i代表每一根木棒的长度 
    52             if (0==sum%i) 
    53             {
    54                 sl=i;
    55                 memset(vis,0,sizeof(vis));
    56                 if (i==sum || dfs(sum/i,n-1,0)) 
    57                 {
    58                     cout<<i<<endl;
    59                     break;
    60                 }
    61             }
    62     }
    63     return 0;
    64 }
  • 相关阅读:
    游戏与必胜策略
    中国剩余定理
    中国剩余定理
    欧几里得和扩展欧几里得
    欧几里得和扩展欧几里得
    51nod 1028 大数乘法 V2
    51nod 1028 大数乘法 V2
    51nod 1029 大数除法
    51nod 1029 大数除法
    51nod 1166 大数开平方
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/4624454.html
Copyright © 2020-2023  润新知