题目大意:
给你n个数字,将其利用剪切和粘贴来排序,问最小步数;
解题思路:
典型的迭代加深搜索,我们可以得知剪贴的最多步数是8,因此我们便可以通过枚举深度来进行搜索,唯一难点在于剪枝的问题,我们知道如果剪切下一段,不管放到哪里,都只会有三个数字的后继会发生变化也就是说,最多能有三个数字的位置能由错误变为正确。因此,当3d + h > 3max时不必再往下搜了,搜不完的。
AC代码:
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define maxn 15
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(x,y) memset(x,y,sizeof(x))
#define mc(x, y) memcpy(x, y, sizeof(x))
#define rep(i,n) for(int i=0;i<(n);i++)
#define repf(i,a,b) for(int i=(a);i<=(b);i++)
#define pii pair<int,int>
//#define mp make_pair
#define FI first
#define SE second
#define IT iterator
#define PB push_back
#define Times 10
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const double eps = 1e-10;
const double pi = acos(-1.0);
const ll mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const ll INF = (ll)1e18+300;
int n;
int a[maxn];
bool judge() {
for (int i = 0; i < n-1; i++) {
if(a[i] >= a[i+1]) {
return false;
}
}
return true;
}
int find() {
int res = 0;
for (int i = 0; i < n-1; i++) {
if(a[i] + 1 != a[i+1]) {
res ++;
}
}
if(a[n-1] != n) {
res ++;
}
return res;
}
bool DFS(int dep, int max_dep) {
if (3 * dep + find() > 3 * max_dep) {
return false;
}
if(judge()) {
return true;
}
for (int i = 0; i < n; i++){
for (int j = i; j < n; j ++) {
int res[maxn];
int ans[maxn];
int cnt = 0;
mc(ans, a);
for (int k = 0; k < n; k++){
if(k < i || k > j) {
res[cnt ++] = a[k];
}
}
for (int k = 0; k <= cnt; k++) {
int num = 0;
for (int pos = 0; pos < k; pos ++) {
a[num ++] = res[pos];
}
for (int pos = i; pos <= j ; pos++) {
a[num++] = ans[pos];
}
for (int pos = k; pos < cnt; pos++) {
a[num++] = res[pos];
}
if(DFS(dep+1, max_dep)) {
return true;
}mc(a, ans);
}
}
}
return false;
}
int solve() {
if(judge()) {
return 0;
}
int max_depth = 8;
for (int i = 0; i < max_depth; i++) {
if(DFS(0, i)) {
return i;
}
}
return max_depth;
}
int main() {
int kase = 0 ;
while(cin >> n && n) {
kase ++;
for (int i= 0; i < n;i ++) {
cin >> a[i];
}
cout << "Case " << kase << ": " << solve() << endl;
}
}