DP之 石子合併1 2 (詳細分析)

2021-10-08 06:26:41 字數 2601 閱讀 1918

設有n堆石子排成一排,其編號為1,2,3,…,n。

每堆石子有一定的質量,可以用乙個整數來描述,現在要將這n堆石子合併成為一堆。

每次只能合併相鄰的兩堆,合併的代價為這兩堆石子的質量之和,合併後與這兩堆石子相鄰的石子將和新堆相鄰,合併時由於選擇的順序不同,合併的總代價也不相同。

例如有4堆石子分別為 1 3 5 2, 我們可以先合併1、2堆,代價為4,得到4 5 2, 又合併 1,2堆,代價為9,得到9 2 ,再合併得到11,總代價為4+9+11=24;

如果第二步是先合併2,3堆,則代價為7,得到4 7,最後一次合併代價為11,總代價為4+7+11=22。

問題是:找出一種合理的方法,使總的代價最小,輸出最小代價。

輸入格式

第一行乙個數n表示石子的堆數n。

第二行n個數,表示每堆石子的質量(均不超過1000)。

輸出格式

輸出乙個整數,表示最小代價。

樣例樣例輸入

41 3 5 2

樣例輸出

22

這一道題,是區間dp的最經典也是最基礎的一道題。二維陣列 f 表示從左區間到右區間這個元區間的最優答案,我們需要 len 表示元區間的長度,而 l 、r 分別表示元區間的左右終點。

重點來了

在任意乙個元區間中,我們需要乙個 k 來表示在元區間中的乙個截點,從而 l 到 k 這個區間最佳 +

k+1至 r 這個區間 便是 l到 r 這個區間的最佳了。

將堆石子繞圓形操場排放,現要將石子有序地合併成一堆。規定每次只能選相鄰的兩堆合併成新的一堆,並將新的一堆的石子數記做該次合併的得分。

請編寫乙個程式,讀入堆數 及每堆的石子數,並進行如下計算:

選擇一種合併石子的方案,使得做 次合併得分總和最大。

選擇一種合併石子的方案,使得做 次合併得分總和最小。

輸入格式

輸入第一行乙個整數 ,表示有 堆石子。

第二行 個整數,表示每堆石子的數量。

輸出格式

輸出共兩行:

第一行為合併得分總和最小值,

第二行為合併得分總和最大值。

樣例

樣例輸入

44 5 9 4

樣例輸出

4354

這道題難點在於石頭的擺放的位置是乙個環,所以我們需要兩倍陣列,即下圖:

其他就跟石子1大同小異了

#include

#include

#include

using

namespace std;

const

int m=

1005

;int f[m]

[m],a[m]

,f2[m]

[m];

int s[m]

,w[m]

[m];

intmain()

for(

int i=n+

1;i<=

2*n-

1;i++

)for

(int len=

2;len<=n;len++

) f[i]

[j]+

=s[j]

-s[i-1]

; f2[i]

[j]+

=s[j]

-s[i-1]

;}}int minn=

100000

,maxn=0;

for(

int i=

1;i)printf

("%d\n%d"

,minn,maxn)

;}

const詳細分析

最近在分析 linux 驅動的過程過程中遇到一些關於 const 的使用,現在在這裡詳細剖析一下 一,const int p 首先分析一下幾個概念 1 p 是乙個指標變數,因而它也是乙個變數,所謂變數就有變數的位址和變數的值,而這裡 p變數的值就是乙個位址,該位址下存放的是乙個整數,p的值等於這個整...

約數詳細分析

約數詳細分析 我們先來認識一下約數 約數分正約數和負約數兩種,我們一般只討論正約數。也就是說,接下來所提的約數,只考慮正約數。如果有乙個數k,滿足k n,那麼k就是n 的約數 因數 n是k的倍數。求乙個數的約數是資訊學競賽裡乙個基礎的不能再基礎的問題。如果只求乙個數,最容易想到的就是列舉。當然列舉也...

vue cli 詳細分析

vue lic 是 vue 官方提供的腳手架工具,預設搭建好乙個專案的基本架子,我們只需要在此基礎上進行相應的修改即可。注意 安裝 vue cli 前需要事先配置好 node 環境 npm install g vue cli 如果是 mac 電 sudo表示以管理員的許可權 sudo install...