有n堆石子排成一排,每堆石子有一定的數量。現要將n堆石子並成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過n-1次合併後成為一堆。求出總的代價最小值。
輸入
有多組測試資料,輸入到檔案結束。
每組測試資料第一行有乙個整數n,表示有n堆石子。
接下來的一行有n(0< n <200)個數,分別表示這n堆石子的數目,用空格隔開
輸出
輸出總代價的最小值,佔單獨的一行
樣例輸入
3
1 2 3
713 7 8 16 21 4 18
樣例輸出
9
239
題目來自:nyoj 737
石子合併是經典的區間dp問題。
本題是將相鄰兩邊進行依次合併,求最小的合併值。
dp[i][j]表示以i為起點,j為終點的合併值。
狀態轉移方程就是遍歷尋找i與j之間一點,進行更新。
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[i][j]);
其中sum陣列的值就是從i到j所有石子值之和。
開始的時候我以為dp[i][i]應該是該堆石子的值,後面發現這是不對的,應該是0,因為這一堆沒有辦法合併,所以最小的合併值就是0.
#include #include #include using namespace std;
const int maxn =210;
const int inf =0x3f3f3f3f;
int a[maxn];
int dp[maxn][maxn];//dp[i][j]表示從i取到j的最小值
int main()
for(int len=2; len<=n; len++)//區間長度}}
printf("%d\n",dp[1][n]);
}return 0;
}
區間dp石子歸併問題
石子歸併 現在有n堆石子,第i堆有ai個石子。現在要把這些石子合併成一堆,每次只能合併相鄰兩個,每次合併的代價是兩堆石子的總石子數。求合併所有石子的最小代價。input 第一行包含乙個整數t t 50 表示資料組數。每組資料第一行包含乙個整數n 2 n 100 表示石子的堆數。第二行包含n個正整數a...
區間dp 石子歸併問題
今天偷玩電腦,就學了幾個模板題,水一水吧 描述 有n堆石子排成一排,每堆石子有一定的數量。現要將n堆石子並成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過n 1次合併後成為一堆。求出總的代價最小值。分析 要求n個石子歸併,我們根據dp的思想劃分成子問題,...
石子歸併 區間DP
n堆石子擺成一條線。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的代價。計算將n堆石子合併成一堆的最小代價。例如 1 2 3 4,有不少合併方法 1 2 3 4 3 3 4 3 6 4 9 10 19 1 2 3 4 1 5 4 5 1 9...