把一摞烙餅按大的在下,小的在上拍好,乙隻手一次只能抓住上面的幾張餅,把它們上下顛倒個個。反覆幾次後把餅排好。
問把餅排好需要的最小的次數。
問題:是看看把餅排好需要的最小次數。
找最優解的問題,可以想到用窮舉法。
用遞迴的方式去遍歷所有的翻轉方式。然後找到最小的值。
可以先把最上面的兩張翻一下,把次數加一,看看是不是達到要求了,如果沒有的話再已經翻轉過的基礎上再繼續遞迴。當順序排好了,這是乙個退出條件。
當然,書中做了優化,對當前餅的順序做了評估,看看還有多少張餅處於不相鄰的位置,給出乙個評估值,如果當前已經執行的翻轉次數+未來還需要翻轉的次數 > 2(n-1)這是需要的最大的翻轉次數時,也就可以直接退出了。
程式中可以關注一下 findswapcount的返回值,如果能優化其中演算法,使其返回值盡量的大(當然要合理),這樣就能大幅的減少遞迴的次數。
例如測試時餅大小的順序是 ,這個最少要翻兩次。當前的程式需要查詢 79次,如果將findswapcount的返回值變成2倍,這樣需要查詢
51次。
如果用進行測試, 375289:39057,這個就比較明顯了。
#include
using
namespace
std;
int nmax = 0;
int nsearchtime = 0;
void print(int *pdata, int nlen)
void swap(int *pdata, int nstart, int nend)
}int findswapcount(int* pdata, int nlen)
}return n;
}bool isok(int *pdata, int nlen)
return
true;
}void search(int nstep, int* pdata, int nlen)
return;
}for (i = 1; i < nlen; i++)
}void main()
;//int nlen = 10;
//int test[5] = ;
//int nlen = 5;
int test[3] = ;
int nlen = 3;
print(test, nlen);
nmax = nlen * 2;
search(0, test, nlen);
cout
<< nmax << " search times: "
<< nsearchtime cin >> value;
}
程式設計之美之烙餅問題
程式設計之美之一摞烙餅.cpp 定義控制台應用程式的入口點。不同的程式會得到不同的結果嗎?有個程式能得到不同的結果,但後來證明他的結果是錯的 該演算法有點在於在於找最少的交換次數,不是在於用最少的時間進行排序,此演算法的排序時間不是最少的。因為演算法的查詢時間太長了。include stdafx.h...
程式設計之美1 3 翻烙餅問題
問題 給定一組隨機數字,使其從大到小排序。要求 只能對陣列做一種操作 翻轉arr 0 至arr n 其中n為大於0小於arrlength的整數 解題思路 搜尋樹演算法 遞迴遍歷 減枝 詳解 1.將該陣列構建為一顆樹,假設該陣列為4,2,1,3 2.目標為如何找到序列為1,2,3,4 深度最小的子節點...
程式設計之美 1 3 烙餅排序問題
問題描述 烙餅問題可以簡化為對一段由n個無重複的整數組成的無序陣列a n 進行排序。排序要求每次只能對a 0 a i 部分的陣列進行翻轉 0 i n 最終完成排序。輸入 陣列大小n n個整數。輸出 最小遞迴查詢次數m 每次翻轉位置j0j1 jm 1。問題思考 烙餅排序這部分,主要考量的是對遞迴函式的...