问题描述:星期五的晚上,一帮同事在希格玛大厦附近的“硬盘酒吧”多喝了几杯。程序员多喝了几杯之后谈什么呢?自然是算法问题。有个同事说:“我以前在餐馆打工,顾客经常点非常多的烙饼。店里的饼大小不一,我习惯在到达顾客饭桌前,把一摞饼按照大小次序摆好——小的在上面,大的在下面。由于我一只手托着盘子,只好用另一只手,一次抓住最上面的几块饼,把它们上下颠倒个个儿,反复几次之后,这摞烙饼就排好序了。我后来想,这实际上是个有趣的排序问题:假设有n块大小不一的烙饼,那最少要翻几次,才能达到最后大小有序的结果呢?”
你能否写出一个程序,对于n块大小不一的烙饼,输出最优化的翻饼过程呢?
运用动态规划的思想。
两个算法进行比较,第一个是从上层开始递归往下,第二个是从下层顺序开始逐步往上,代码如下:
#include<iostream>
using namespace std;
class CPrefixSorting
{
public:
CPrefixSorting(int *_data,int length);
void Revert();
void RevertDP();
void Output();
private:
int maxstep;
int height;
int *data;
};
CPrefixSorting::CPrefixSorting(int *_data,int length)
{
data = new int[length + 1];
for(int i = 1; i <= length; i++)
data[i] = _data[i];
maxstep = 0;
height = length;
}
void CPrefixSorting::Revert()
{
int top = 1;
int bottom = 2;
int tempheight = bottom - top;
int i,j;
while(tempheight < height)
{
if(data[bottom] < data[bottom - 1])
{
for(i = 1;i < bottom; i++)
{
if(data[1] > data[bottom])
{
for(j = 0; j < bottom; j++)
{
data[j] = data[j + 1];
}
data[bottom] = data[0];
}
else
{
for(j = 0; j < bottom - 1; j++)
{
data[j] = data[j + 1];
}
data[bottom - 1] = data[0];
}
maxstep++;
}
}
tempheight++;
bottom = tempheight + 1;
}
}
void CPrefixSorting::RevertDP()
{
int top = height;
int bottom = height;
int i,j;
while(top != 1) //确定已有的底层顺序
{
if(data[top - 1] > data[top])
break;
top--;
}
while(top != 1)
{
for(i = bottom; i >= top; i--)
{
if(data[i] < data[1])
break;
}
if(i == 1)
break;
for(j = 0; j < i; j++)
data[j] = data[j + 1];
maxstep++;
cout<<"step "<<maxstep<<" : "<<data[0]<<" insert after "<<data[j]<<endl;
data[j] = data[0];
top--;
}
}
void CPrefixSorting::Output()
{
cout<<"we need step "<<maxstep<<" to complete the sort!"<<endl;
for(int i = 1; i <= height; i++)
cout<<data[i]<<" ";
cout<<endl;
}
int main()
{
int data[] = {-1,4,2,1,5,3};
cout<<"the init sequence : 4,2,1,5,3"<<endl;
CPrefixSorting cpfs(data,5);
cpfs.RevertDP();
cpfs.Output();
return 0;
}