• Sticks


    By cuizhenkai

    1.优化搜索顺序

    从小到大排序, 优先尝试较长的木棍。

    理解:

    • 从最大开始可以较快的排除不可能的分支,避免dfs进入比较深的树。
    • 若从最小开始,则有可能前几根可以拼好,但是后面的不能满足条件,让dfs进入了更深的层。

    2. 排除等效冗余

    A ) 限制先后加入一根原始木棍的长度递减

    理解:

    • 先拼长度为 $x$,再拼为 $y$ 的木棍 $(x < y)$ 与反之是等效的。

    B ) 对于当前原始木棒,记录最近一次尝试拼接的长度,如果失败回溯,不再向该木棒中添加一样长的木棍。

    —— 这个比较好理解。

    C ) 若在当前原始木棒中,尝试的第一根木棍就失败,那么该分支失败。

    理解:

    • 按照上面的剪枝,我们可以知道,对一根原始木棒,尝试的第一根木棍就失败,意味着其他的空木棒也必定失败。

    D ) 若向一根原始木棒拼接了一根木棍后,恰好成功,但是下面的分支失败,那么此分支失败

    理解:

    • 用一根拼好比用若干根其他木棍拼好要更优,原因是长度小的木棍更灵活。

    Code:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54

    大专栏  Stickspan class="meta">#include <iostream>
    #include <algorithm>
    #include <cstring>

    using namespace std;

    int a[105];
    int vis[105];
    int n = 0;
    int len = 0;
    int cnt = 0;
    int ans;

    bool (int s, int now, int last) {
    if(s > cnt) {return true;}
    if(now == len) {return dfs(s + 1, 0, 1);}
    int fail = 0;
    for(int i = last; i <= ans; i ++) {
    if(!vis[i] && now + a[i] <= len && fail != a[i]) {
    vis[i] = 1;
    if(dfs(s, now + a[i], i + 1)) {return true;}
    fail = a[i];
    vis[i] = 0;
    if(now == 0 || now + a[i] == len) {return false;}
    }
    }
    return false;
    }

    int main(int argc, char const *argv[]) {
    scanf("%d", &n);
    int tot = 0;
    int maxm = 0;
    for(int i = 1; i <= n; i ++) {
    int x;
    scanf("%d", &x);
    if(x <= 50) {
    a[++ans] = x;
    tot += a[ans];
    maxm = max(maxm, a[ans]);
    }
    }
    sort(a + 1, a + ans + 1);
    reverse(a + 1, a + ans + 1);
    for(len = maxm; len <= tot; len ++) {
    if(tot % len) continue;
    cnt = tot / len;
    memset(vis, 0, sizeof(vis));
    if(dfs(1, 0, 1)) {break;}
    }
    printf("%d", len);
    return 0;
    }

    实现时的错误:

    • 对于剪枝D的理解不清。
  • 相关阅读:
    [数据知识]DAMA数据管理—引论
    How to clear/delete all the partition table from a disk or partition in Linux
    Rust Safe Coding Notes
    量化交易平台
    斯坦福大学——人工智能本科4年课程清单
    去中心化数字身份DID简介——五、DID的应用
    linux c 打印时间最简单的实例
    sqlalchemy中Column的默认值属性
    Ubuntu安装jdk8的两种方式
    面试官:手撕十大排序算法,你会几种?(转)
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12360837.html
Copyright © 2020-2023  润新知