洛谷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;
}