程式設計之美 烙餅問題

2021-07-09 05:11:54 字數 1372 閱讀 9582

把一摞烙餅按大的在下,小的在上拍好,乙隻手一次只能抓住上面的幾張餅,把它們上下顛倒個個。反覆幾次後把餅排好。

問把餅排好需要的最小的次數。

問題:是看看把餅排好需要的最小次數。

找最優解的問題,可以想到用窮舉法。

用遞迴的方式去遍歷所有的翻轉方式。然後找到最小的值。

可以先把最上面的兩張翻一下,把次數加一,看看是不是達到要求了,如果沒有的話再已經翻轉過的基礎上再繼續遞迴。當順序排好了,這是乙個退出條件。

當然,書中做了優化,對當前餅的順序做了評估,看看還有多少張餅處於不相鄰的位置,給出乙個評估值,如果當前已經執行的翻轉次數+未來還需要翻轉的次數 > 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。問題思考 烙餅排序這部分,主要考量的是對遞迴函式的...