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