思路:刘汝佳紫书上的题,设maxd为深度上限,最大为8.当前深度为d,,用h()计算当前后继不正确的数。 剪枝条件为h()>3*(maxd-d),即h()+3d>3maxd.
c++代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int a[15];
int n;
int maxd;
bool is_sorted() {
for(int i=1;i<n;i++)
if(a[i]!=a[i-1]+1)return false;
return true;
}
int h() {
int cnt=0;
for(int i=1;i<n;i++)
if(a[i]!=a[i-1]+1)cnt++;
if(a[0]!=1)cnt++;
return cnt;
}
bool dfs(int d) {
if(is_sorted()){
return true;
}
//cout << h()<<endl;
if(3*d+h()>3*maxd)return false;
int b[15],o[15];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++) {
int cnt2=0;
memcpy(o,a,sizeof(a));
for(int k=0;k<n;k++)
{
//cout << i <<" " <<j <<endl;
if(k<i||k>j)b[cnt2++]=a[k];
}
//遍历插入位置
int cnt;
for(int k=0;k<cnt2;k++) {
cnt=0;
//cout << "d="<<d <<endl;
for(int t=0;t<k;t++)a[cnt++]=b[t];
for(int t=i;t<=j;t++)a[cnt++]=o[t];
for(int t=k;t<cnt2;t++)a[cnt++]=b[t];
//if(is_sorted())return true;
/*
*/
if(dfs(d+1))return true;
}
memcpy(a,o,sizeof(o));
}
return false;
}
int main() {
int kase=0;
while(scanf("%d",&n)!=EOF&&n) {
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
if(is_sorted()) {
printf("Case %d: %d\n",++kase,0);
continue;
}
for(maxd=1;maxd<=8;maxd++) {
//cout << maxd << endl;
if(dfs(0)) {
printf("Case %d: %d\n",++kase,maxd);
break;
}
}
}
return 0;
}