《编程之美》1.3节:
主要是递归求解,还有就是剪枝的问题,这里提出的剪枝方法:当现在已经进行的反转次数加上可能的最少次数仍然比当前得到的最小次数多时,就需要剪枝了,因为即使计算到最后也不可能找到一个比当前算法更优的解。
书上是用类写的,我为了简单,就直接用函数了。A[0]表示最小的饼应该处于的位置。
#include<iostream>
#include<algorithm>
using namespace std;
int Array[20];
int result[20];
bool isSorted(int A[],int N)
{
for(int i=1;i<N;i++)
{
if(A[i]<A[i-1])
return false;
}
return true;
}
void reverse(int A[],int N)
{
int temp=0;
for(int i=0;i<(N+1)>>1;i++)
{
temp=A[i];
A[i]=A[N-i];
A[N-i]=temp;
}
}
int minReverse(int A[],int N)
{
int num=0;
for(int i=1;i<N;i++)
{
int t=A[i-1]-A[i];
if(t!=1 && t!=-1)
num++;
}
return num;
}
void search(int A[],int N,int &step,int &minStep)
{
if(step+minReverse(A,N)>=minStep)
return ;
if(isSorted(A,N))
{
if(step<minStep)
{
minStep=step;
for(int i=0;i<minStep;i++)
result[i]=Array[i];
for(int i=minStep;i<20;i++)
result[i]=0;
}
return ;
}
for(int i=1;i<N;i++)
{
reverse(A,i);
Array[step]=i;
step++;
search(A,N,step,minStep);
step--;
reverse(A,i);
}
}
int main()
{
const int N=10;
int A[N];
generate(A,A+N,rand);
int step=0,minStep=20;
search(A,N,step,minStep);
system("pause");
return 0;
}