zoukankan      html  css  js  c++  java
  • POJ 1011 Sticks(DFS+剪枝)

    题目链接:http://poj.org/problem?id=1011

    剪枝策略:

    1.优化搜索顺序:

    将每一段木棒的长度从大到小排序。

    2.排除等效冗余:

    (1)设两根木棒长度分别为x,y,且x<y,那么先拼上x再拼y和先拼y再拼x是等效的,只需要搜索其中的一种。那么可以限制选的顺序为递减的。

    (2)对于当前的木棒,可以记录最近一次尝试拼入的木棍长度。如果分支搜索失败回溯,不再向该木棒中加入其他长度相同的木棍(因为必定也会失败)。

    (3)如果在当前原始木棒尝试拼入第一根木棍的递归就返回失败,那么直接判定整个分支失败,立即回溯。因为在拼入这根木棒前,所有的原始木棒都是空的。木棒在拼当前木棒中失败,在拼其他木棒中一样会失败。

    (4)如果在当前原始木棒中拼入一根木棍后,木棒恰好被拼接完整,并且接下来拼接剩余原始木棒的递归分支失败,那么可以判定整个分支失败。(可以用贪心来解释)

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 const int N=80;
     7 int n,len,cnt,val,sum;
     8 int vis[N],a[N];
     9 bool cmp(int x,int y){
    10     return x>y;
    11 }
    12 bool DFS(int stick,int now,int last){
    13     if(stick>cnt) return 1;
    14     if(now==len) return DFS(stick+1,0,1);
    15     int fail=0;
    16     for(int i=last;i<=n;i++){
    17         if(!vis[i]&&now+a[i]<=len&&fail!=a[i]){
    18             vis[i]=1;
    19             if(DFS(stick,now+a[i],i+1)) return 1;
    20             fail=a[i];
    21             vis[i]=0;
    22             if(now==0||now+a[i]==len) return 0;
    23         }
    24     }
    25     return 0;
    26 }
    27 int main(){
    28     while(~scanf("%d",&n)&&n){
    29         sum=val=0;
    30         for(int i=1;i<=n;i++) scanf("%d",&a[i]),val=max(val,a[i]),sum+=a[i];
    31         sort(a+1,a+n+1,cmp);
    32         for(len=val;len<=sum;len++){
    33             if(sum%len) continue;
    34             cnt=sum/len;
    35             memset(vis,0,sizeof(vis));
    36             if(DFS(1,0,1)) break;
    37         }
    38         printf("%d
    ",len);
    39     }
    40     return 0;
    41 }
    AC代码
  • 相关阅读:
    SQL server 2008 建立新用户
    2021.3.22-刷题 (移位)
    2021.3.17刷题-分割回文串
    2021.3.16 刷题--组合总和||(一种组合下元素不可重复选取)
    2021.3.15刷题-组合总和(元素可重复选取)
    2021.3.14刷题-设计哈希映射
    2021.3.13刷题-用拉链法设计哈希集合
    2021.3.12刷题-验证二叉树的前序序列化
    2021.3.11刷题-(删除二叉搜索树中的节点)
    2021.2.28刷题 回溯-电话字母组合
  • 原文地址:https://www.cnblogs.com/New-ljx/p/13927706.html
Copyright © 2011-2022 走看看