區間動規經典題 石子合併

2021-07-28 17:59:39 字數 1293 閱讀 5170

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

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

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

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

4

4 5 9 4

43

54

區間動態規劃問題一般都是考慮,對於每段區間,他們的最優值都是由幾段更小區間的最優值得到,是分治思想的一種應用,將乙個區間問題不斷劃分為更小的區間直至乙個元素組成的區間,列舉他們的組合 ,求合併後的最優值

由題意可得這些石子是擺放成乙個環,環形不好寫狀態轉移方程,那我們就可以把它拆成一條長度為2*n-1的鏈,採用區間動規的辦法,合併的石子數用字首和優化一下就好了

狀態轉移方程:

f[i][j]表示從第i堆石子到第j堆石子的最大/最小得分,用k(i<=k<=j-1)將區間分成[i,k]和[k+1,j]兩個區間

初值:f[i][i]=0

fmax[i][j]=max

fmin[i][j]=min

#include

#include

#define maxn 2*100+5

#define inf 10000000

int fmax[maxn][maxn],fmin[maxn][maxn],s[maxn],n,max_ans=-inf,min_ans=inf;

inline

int maxx(int x,int y)

inline

int minn(int x,int y)

}for(i=1;i<=2*n-1;++i)

fmax[i][i]=fmin[i][i]=0;

for(i=2*n-1-1;i>=1;--i)}}

}void get_ans()

}int main()

for(i=1;i<=2*n-1;++i)

s[i]+=s[i-1];//字首和優化

dp();

get_ans();

printf("

%d\n%d\n

",min_ans,max_ans);

return

0;}

區間動規經典題 石子合併

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

石子合併(區間型動規)

在乙個圓形操場的四周擺放n堆石子 n 500 現要將石子有次序地合併成一堆。規定每次只能選相鄰的兩堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。編一程式,由檔案讀入堆數n及每堆的石子數 選擇一種合併石子的方案,使得做n 1次合併,得分的總和最小 選擇一種合併石子的方案,使得做n 1次合...

動規之 環形石子合併

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