在乙個圓形操場的四周擺放著n堆石子,現要將石子有次序地合併成一堆。規定每次只能選擇相鄰的兩堆石子合併成新的一堆,並將新一堆石子數記為該次合併的得分。試設計乙個動態規劃演算法,計算出將n堆石子合併成一堆的最小得分和最大得分,要求列出遞迴方程,寫出演算法的偽**並分析演算法的時間空間複雜性。
要求每次合併必須是相鄰的,和矩陣鏈乘的括號作用差不多。可以考慮往矩陣鏈乘最小代價的遞迴方程上靠。設dp[i,j]為第i堆到第j堆合併的最優解,則\(dp[i,j] = min\\)
注意由於是圓形,而矩陣鏈乘是線性的,所以這個遞迴方程勢必需要修改。考慮如何表示環,乙個自然的想法是利用mod函式。遞迴方程修改如下,為了方便表示修改dp[i,j]定義如下:從第i堆開始合併j堆的最優解。(否則需要填寫的項數不全在乙個矩陣半形上)
\(dp[i,j] = min\~~~~ i<=k<=j\)
\(dp[i,j] = max\~~~~ i<=k<=j\)
總覺得和之前那道折木棒的很像,畫個解的樹表示看看,發現幾乎一致,同樣是求樹的所有內部節點的值的和。但是不同的是,對葉節點有限制,即從左到右需要嚴格按照\(v_1, v_2, ..., v_n\) 排列。那麼同樣可以利用哈夫曼樹的思想解決。維護乙個葉節點的陣列,每次選擇相鄰中最小最大的一組\((v_i, v_j)\),生成乙個子樹,同時將\(v_i,v_j\)刪去,新的葉節點\(v_i+v_j\)放入原來\(v_i\)位置。同樣可解問題。
直覺兩者應該是乙個系列的題,去bing一下。果不其然:
一道作業題
時間限制 1000 ms 記憶體限制 64 mb 題目描述 初始有乙個數n,每過一秒所有大於1的數x都會 成3部分 x 2 x 2 x 2 問經過足夠長的時間後,即所有的數都是0或1的時候,0的個數是多少.輸入資料 乙個正整數n,n 1e12 輸出資料 最終0的個數 樣例輸入 5樣例輸出 2樣例說明...
最近做的一道c 作業題
今天突然想到,接觸這玩意快一年了,結果還是弱雞乙隻。一直跟自己說慢慢來,但是覺得,還是不能慢慢來,雖然想好好學習,但一直只是想。有時候想什麼高數什麼大物都不寫,但是囿於現實,沒辦法。沒地方說事情就在這裡巴拉巴拉一大堆先。看題吧 實驗內容 實驗 編寫乙個人員資訊管理系統。這個系統的功能是 互動式的實現...
一道簡單的作業題的延伸,最優化的演算法
題目 2 0 2 1 2 2 2 3 2 4.2 31 2的次方相加,不要使用math庫的pow函式 譚浩強 版,效率最低,兩次遍歷 includeint main void printf sum lld n sum 最優化版,位運算 include int main int argc,char a...