洛谷P2534 [AHOI2012]铁盘整理 题解 IDA*搜索

题目链接:https://www.luogu.com.cn/problem/P2534

解题思路:

IDA*搜索。

首先需要离散化一下,\(\Rightarrow\) \(n\) 个数变为了 \(0 \sim n-1\)

然后估价函数 \(h()\) 可以定义为相邻元素相差不为 \(1\) 的对数,当然如果 \(n\) 个数的排列为 \(n-1,n-2, \cdots, 2, 1\),则对应的 \(h()=1\)(因为还需要整体翻转一次)。

示例代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 20;
int n, a[maxn], b[maxn];

int h() {   // 估计函数为最少需要翻转的次数
    int cnt = 0;
    for (int i = 1; i < n; i ++) {
        if (abs(a[i] - a[i-1]) > 1)
            cnt ++;
    }
    if (a[0] && !cnt) cnt ++;
    return cnt;
}

int D;

bool dfs(int d, int pre) {
    if (d + h() > D) return false;
    if (h() == 0) return true;
    for (int i = 2; i <= n; i ++) {
        if (i == pre) continue; // 不与上一轮翻转的长度相同
        reverse(a, a+i);
        if (dfs(d+1, i)) return true;
        reverse(a, a+i);
    }
    return false;
}

int solve() {
    for (D = 0; ; D ++)
        if (dfs(0, -1))
            return D;
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i ++) {
        scanf("%d", a+i);
        b[i] = a[i];
    }
    sort(b, b+n);
    for (int i = 0; i < n; i ++)    // 离散化
        a[i] = lower_bound(b, b+n, a[i]) - b;
    printf("%d\n", solve());
    return 0;
}
posted @ 2020-09-28 21:58  quanjun  阅读(140)  评论(0编辑  收藏  举报