参照紫书给出的算法,利用搜索,每次划定一个不变的部分以及一个相应的变化的部分,对变化的部分不断地选择剪切的点,然后将剪切得到的部分和不变的部分进行连接,得到结果之后再进行判断即可。具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
using namespace std;
int n;
int a[10];
bool Sorted(){
for (int i = 0; i < n-1; i++){
if (a[i] >= a[i + 1]) return false;
}
return true;
}
int distance(){
int amount = 0;
for (int i = 0; i < n-1; i++){
if (a[i]+1 != a[i + 1]) amount++;
}
if (a[n - 1] != n) amount++;
return amount;
}
int Solve(int cur_d,int max_d){
if (3 * cur_d + distance()>3 * max_d) return 0;
if (Sorted()) return 1;
int tempa[10], tempb[10];
memcpy(tempa,a,sizeof(a));
for (int i = 0; i < n; i++){
for (int j = i; j < n; j++){
int count_b = 0;
for (int k = 0; k < n; k++){
if (k<i || k>j) tempb[count_b++] = a[k];
}
for (int k = 0; k <= count_b; k++){
int index = 0;
for (int t = 0; t < k; t++) a[index++] = tempb[t];
for (int t = i; t <= j; t++) a[index++] = tempa[t];
for (int t = k; t < count_b; t++) a[index++] = tempb[t];
if (Solve(cur_d + 1, max_d)) return 1;
memcpy(a,tempa,sizeof(tempa));
}
}
}
return 0;
}
int main(){
int Case = 1;
while (cin >> n&&n){
int i;
for (i = 0; i < n; i++) cin >> a[i];
if (Sorted()){
cout << "Case " << Case++ << ": " << 0 << endl;
continue;
}
for (i = 1; i < n; i++){
if (Solve(0, i)) break;
}
cout <<"Case "<<Case++<<": "<< i << endl;
}
return 0;
}