zoukankan      html  css  js  c++  java
  • POJ1011 Sticks

    POJ1011 Sticks

    剪枝好题,具体见代码:

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cctype>
     5 #include <iostream>
     6 using namespace std;
     7 
     8 inline int read()
     9 {
    10     int f=1,x=0; char ch;
    11     while(!isdigit(ch=getchar())) if(ch=='-') f=-1;
    12     while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
    13     return f*x;
    14 }
    15 
    16 #define res register int
    17 const int N=100;
    18 int a[N],used[N],n,sum,m,ok,len;
    19 bool cmp(const int &x,const int &y){return x>y;}
    20 
    21 void dfs(int now,int last,int rest)
    22 {
    23     if(rest==0)
    24     {    
    25         int i;
    26         if(now==m) {ok=1; return ;}
    27         for(i=1 ; i<=n ; i++) if(!used[i]) break;
    28         used[i]=1; dfs(now+1,i,len-a[i]);
    29         used[i]=0; if(ok) return ;
    30     }
    31     
    32     for(res i=last+1 ; i<=n ; i++)
    33     {
    34         if(!used[i]&&a[i]<=rest)
    35         {
    36             used[i]=1;    dfs(now,i,rest-a[i]);    used[i]=0;
    37             if(ok)    return ;
    38             while(a[i+1]==a[i]) i++;//
    39             if(rest==len||rest==a[i]) return ; 
    40         }
    41         if(i==n) return ; 
    42     }
    43 }
    44 
    45 /*剪枝:
    46 1.把小木棍从大到小排序,先拼大的
    47 2.从小到大枚举原始木块长度len,成立了就直接输出答案。范围:最短的木棍到所有木棍
    48 长度之和的一半,且len需要整除sum
    49 3.当一个木棍不能拼时,和它长度相等的木棍显然也不能拼
    50 4.枚举下一个要拼的木棍时只需从上一个用过的木块的下一个开始枚举
    51 ****5.如果当前长棍剩余的未拼长度等于当前正在试着拼的木块的长度或者等于原始长度(即
    52 刚开始拼),继续拼下去却失败了,则直接回溯,结束枚举。 
    53 */ 
    54 int main()
    55 {
    56 
    57     while(scanf("%d",&n)==1 && n)
    58     {
    59         sum=0;ok=0;
    60         memset(used,0,sizeof(used));
    61         memset(a,0,sizeof(a));
    62         for(res i=1 ; i<=n ; i++)
    63         {
    64             a[i]=read();
    65             sum+=a[i];
    66         }
    67         sort(a+1,a+n+1,cmp);
    68         for(len=a[1] ; len<=sum/2+1 ; len++)
    69         {
    70             if(sum%len!=0) continue;
    71              used[1]=1; m=sum/len;
    72             ok=0;
    73              dfs(1,1,len-a[1]);
    74              used[1]=0;
    75             if(ok) 
    76             {
    77                     printf("%d
    ",len);
    78                     break;
    79             }
    80         }
    81         if(!ok) printf("%d
    ",sum);
    82     }
    83     return 0;
    84 }
    View Code
  • 相关阅读:
    double 和 int 同时存在时的运算
    快速排序
    案例:商品放大镜效果
    淘宝flexible.js源码分析
    案例:模态框拖拽
    Web APIs——BOM
    案例:获取URL参数数据
    案例:5秒之后自动跳转页面
    JS中this指针的指向
    按钮:点击发送短信按钮60秒内不能再次点击的功能
  • 原文地址:https://www.cnblogs.com/wmq12138/p/10369150.html
Copyright © 2011-2022 走看看