Acwing-----算法提高课第二章搜索(六)

170. 加成序列

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 110;
int n, path[N];

bool dfs(int u, int depth) {
    if (u > depth) return false;
    if (path[u - 1] == n) return true;
    
    bool st[N] = {0};
    for (int i = u - 1; i >= 0; --i) {
        for (int j = i; j >= 0; --j) {
            int s = path[i] + path[j];
            if (s > n || s <= path[u - 1] || st[s]) continue;
            
            st[s] = true;
            path[u] = s;
            if (dfs(u + 1, depth)) return true;
        }
    }
    return false;
}

int main() {
    path[0] = 1;
    while (cin >> n, n) {
        int depth = 1;
        while (!dfs(1, depth)) depth++;
        for (int i = 0; i < depth; ++i) cout << path[i] << " ";
        cout << endl;
    }
    return 0;
}

171. 送礼物

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 46;
typedef long long LL;

int n, m, k, w[N], weights[1 << 25], cnt = 1, ans;

void dfs1(int u, int s) {
    if (u == k) {
        weights[cnt++] = s;
        return;
    }
    dfs1(u + 1, s);
    if ((LL)s + w[u] <= m) dfs1(u + 1, s + w[u]);
}

void dfs2(int u, int s) {
    if (u >= n) {
        int l = 0, r = cnt - 1;
        while (l < r) {
            int mid = (l + r + 1) / 2;
            if (weights[mid] <= m - s) l = mid;
            else r = mid - 1;
        }
        ans = max(ans, weights[l] + s);
        return;
    }
    dfs2(u + 1, s);
    if ((LL)s + w[u] <= m) dfs2(u + 1, s + w[u]);
}

int main() {
    cin >> m >> n;
    for (int i = 0; i < n; ++i) cin >> w[i];
    
    sort(w, w + n);
    reverse(w, w + n);
    
    k = n / 2 + 2;
    dfs1(0, 0);
    
    sort(weights, weights + cnt);
    cnt = unique(weights, weights + cnt) - weights;
    
    dfs2(k, 0);
    cout << ans << endl;
    return 0;
}

180. 排书

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 15;
int n, q[N], w[5][N];

int f() {
    int tot = 0;
    for (int i = 0; i + 1 < n; ++i) {
        if (q[i + 1] != q[i] + 1) tot++;
    }
    return (tot + 2) / 3;
}

bool check() {
    for (int i = 0; i + 1 < n; ++i) {
        if (q[i + 1] != q[i] + 1)   return false;
    }
    return true;
}

bool dfs(int depth, int max_depth) {
    if (depth + f() > max_depth) return false;
    if (check()) return true;

    for (int len = 1; len <= n; ++len) {
        for (int l = 0; l + len - 1 < n; ++l) {
            int r = l + len - 1;
            for (int k = r + 1; k < n; ++k) {
                memcpy(w[depth], q, sizeof q);
                int x, y;
                for (x = r + 1, y = l; x <= k; ++x, ++y) q[y] = w[depth][x];
                for (x = l; x <= r; ++x, ++y) q[y] = w[depth][x];
                if (dfs(depth + 1, max_depth)) return true;
                memcpy(q, w[depth], sizeof q);
            }
        }
    }
    return false;
}

int main()
{
    int T;
    cin >> T;
    while (T--) {
        cin >> n;
        for (int i = 0; i < n; i ++ ) cin >> q[i];

        int depth = 0;
        while (depth < 5 && !dfs(0, depth)) depth ++ ;
        if (depth >= 5) puts("5 or more");
        else cout << depth << endl;
    }
    return 0;
}

181. 回转游戏

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 24;

int op[8][7] = {
    {0, 2, 6, 11, 15, 20, 22},
    {1, 3, 8, 12, 17, 21, 23},
    {10, 9, 8, 7, 6, 5, 4},
    {19, 18, 17, 16, 15, 14, 13},
    {23, 21, 17, 12, 8, 3, 1},
    {22, 20, 15, 11, 6, 2, 0},
    {13, 14, 15, 16, 17, 18, 19},
    {4, 5, 6, 7, 8, 9, 10}
};

int oppo[8] = {5, 4, 7, 6, 1, 0, 3, 2};
int center[8] = {6, 7, 8, 11, 12, 15, 16, 17};
int q[N], path[100];

int f() {
    int sum[4] = {0};
    for (int i = 0; i < 8; ++i) sum[q[center[i]]]++;
    int s = 0;
    for (int i = 1; i <= 3; ++i) s = max(sum[i], s);
    return 8 - s;
}

void operape(int x) {
    int t = q[op[x][0]];
    for (int i = 0; i < 6; ++i) q[op[x][i]] = q[op[x][i + 1]];
    q[op[x][6]] = t;
}

bool dfs(int depth, int max_depth, int last) {
    if (depth + f() > max_depth) return false;
    if (f() == 0) return true;
    
    for (int i = 0; i < 8; ++i) {
        if (last != oppo[i]) {
            operape(i);
            path[depth] = i;
            if (dfs(depth + 1, max_depth, i)) return true;
            operape(oppo[i]);
        }
    }
    return false;
}

int main() {
    while (cin >> q[0], q[0]) {
        for (int i = 1; i < 24; i ++ ) cin >> q[i];

        int depth = 0;
        while (!dfs(0, depth, -1)) depth ++ ;

        if (!depth) printf("No moves needed");
        else {
            for (int i = 0; i < depth; i ++ ) printf("%c", 'A' + path[i]);
        }
        printf("\n%d\n", q[6]);
    }

    return 0;
}
posted @ 2020-10-04 19:17  景云ⁿ  阅读(142)  评论(0)    收藏  举报