洛谷 1880 NOI1995 石子合併

2021-09-23 22:08:44 字數 1515 閱讀 1439

題目描述

在乙個圓形操場的四周擺放n堆石子,現要將石子有次序地合併成一堆.規定每次只能選相鄰的2堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。

試設計出1個演算法,計算出將n堆石子合併成1堆的最小得分和最大得分.

輸入輸出格式

輸入格式:

資料的第1行試正整數n,1≤n≤100,表示有n堆石子.第2行有n個數,分別表示每堆石子的個數.

輸出格式:

輸出共2行,第1行為最小得分,第2行為最大得分.

輸入輸出樣例

輸入樣例#1:

44 5 9 4

輸出樣例#1:

4354

解釋:很明顯區間dp,以最大值為例,設dp[

i][j

]:

dp[i][j]:

dp[i][

j]:從i−j

i-ji−

j的合併最大值,那麼dp[

i][j

]=ma

x(dp

[i][

j],d

p[i]

[k]+

dp[k

+1][

j]+a

[i]+

..a[

j]

)dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+a[i]+..a[j])

dp[i][

j]=m

ax(d

p[i]

[j],

dp[i

][k]

+dp[

k+1]

[j]+

a[i]

+..a

[j])

,環的話只需要單獨處理一下a[i

]+..

.a[j

]a[i]+...a[j]

a[i]+.

..a[

j]就可以了其他一樣

#include#include#define n 103

using namespace std;

long long a[n]=;

long long dp[n][n]=;

int n=0;

long long ret1=0,ret2=0;

void init()

int main()}}

ret2=dp[1][n];

for(int i=2;i<=n;i++) ret2=max(ret2,dp[i][i-1]);

init();

for(int len=1;len}

}ret1=dp[1][n];

for(int i=2;i<=n;i++) ret1=min(ret1,dp[i][i-1]);

cout

}

洛谷1880 NOI1995 石子合併

題目 石子合併 思路 斷環為鏈。sum i 為原序列的字首和。令f i,j 為一段以i為起點長度為j的石子合併需要的最小代價。轉移方程 f i j min f i j f i k i 1 f k 1 ed k sum ed sum i 1 其中,k為劃分點,ed為這一段石子的末位置,即i j 1。主...

洛谷 P1880 NOI1995 石子合併

這道題是之前石子合併的加強板 不同在於是乙個環 處理方法就是把陣列 乘以2,列舉起點轉化成鏈。以後這種環的問題應該都可以這樣來轉化。陣列空間不要忘了乘以2 然後要注意區間從長度為2開始,初始化為最大或最小 注意這裡的得分是合併之後的得分,所以單獨一堆是沒有得分的。include include in...

洛谷 P1880 NOI1995 石子合併

在乙個圓形操場的四周擺放n堆石子,現要將石子有次序地合併成一堆.規定每次只能選相鄰的2堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。試設計出1個演算法,計算出將n堆石子合併成1堆的最小得分和最大得分.輸入格式 資料的第1行試正整數n,1 n 100,表示有n堆石子.第2行有n個數,分別...