問題描述
不同應用背景分析
**及注釋總結
問題描述
目前有n堆果子,現在要將果子兩兩合併為一堆,每一次合併,可以把兩堆果子合併到一起
消耗的體力等於兩堆果子的重量之和。可以看出,所有的果子經過 n−1 次合併之後, 就只剩下一堆了。合併果子時總共消耗的體力等於每次合併所耗體力之和。假定每個果子重量都為 111 ,並且已知果子的堆 數和每堆果子的數目,你的任務是設計出合併的次序方案,使多多耗費的體力最少,並輸出這個最小的體力耗費值。
例如:有3堆果子,每堆數量分別是1,2,9.可以先將1,2合併,耗費體力為3,將新堆與原來的第三堆合併,得到新堆12,耗費體力12。所以耗費的總體力為15.
不同應用背景:
合併果子時,對合併操作更嚴格,要求每次只能合併相鄰兩堆果子。
合併果子時,對合併操作無要求,可以任意合併兩堆果子。
這兩種不同的問法,所對應的解題演算法和思路是完全不一樣的,讀者遇到題目時非常容易想當然,忽略細節。
第一種情況:涉及到區間dp,當只有兩堆時,毫無疑問直接合併;當有三堆果子時,此時的最優解依賴於兩種子問題(1.先合併第
一、二堆,再合併第三堆。2先合併第
二、三堆。再然後合併第一堆),當涉及更多堆果子時,依次類推。這樣滿足最優子結構性質,大問題最優依賴於很多小問題最優,考慮dp.用dp[i] [j]陣列記錄第i到第j堆的耗費的最少體力
dp公式:
i!=j,dp[i][j]=min(dp[i][k]+dp[k+1][j]+sum[i][j]
i==j dp[i][j]=0;
第二種情況:由於任意合併兩堆果子,貪心演算法非常明顯了,即每次合併數目最少的兩堆果子,重複操作n-1次。畫出結構圖,可以看出就是大頂堆的資料結構,考慮到每次操作都要找出最少和次少的果堆,我們就採用優先佇列的儲存結構,儲存資料。
**及注釋
任意相鄰:
#include
#include
using
namespace std;
intmain()
while
(q.size()
>1)
printf
("%d"
,sum)
;return0;
}
相鄰合併:
#include
#include
#define n 201
#define inf 0x3f3f3f3f
using
namespace std;
intmain()
//只有一堆時,無需合併
for(len=
1;len}printf
("%d\n"
,dp[1]
[n])
;return0;
}int
min(
int x,
int y)
總結:
學習程式設計,提高演算法能力,應注重歸納總結,學習完一門演算法之後,馬上找相應的題目上機練習,逐漸練就一題多解,舉一反三。
希望本例程對讀者有用並能激發你的思考,最後祝刷到這條部落格的朋友們,今年暴富,願望成真!
合併兩個陣列的兩種方式的異同
本文討論合併陣列的兩種方式 a b array merge a,b 操作符 在前乙個數的基礎上插入後乙個陣列,假設有同樣的拋棄,而array merge 是在前乙個引數基礎上插入後乙個引數。假設有同樣用的key 用後乙個覆蓋。實比例如以下 php a array a 1 b 2 c 3 php b ...
c語言的兩種排序方式(合併與快速)
合併排序 自定義型別 void swap type a,type b intpartition type a,int p,int r 把初始值換到中間,滿足演算法的思想 a p a j a j x return j void sort type a,int p,int r int main sort...
兩種不同的盒模型
邊框 border 外邊距 margin 內邊距 padding 元素的邊框就是圍繞在內容和內邊距的一條或多條線,它的屬性是border 邊框有三個屬性值1.寬度 2.樣式 3.顏色 border width style color 寬度樣式 solid 實線 dashed 虛線 dotted 點狀...