設有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)。
輸出格式
輸出一個整數,表示最小代價。
數據範圍
1≤N≤300
輸入樣例:
4
1 3 5 2
輸出樣例:
22
#include<iostream>
using namespace std;
const int N=310;
int s[N];//前綴和
int f[N][N];//全局變量默認初始化爲0
int n;
int main(){
cin>>n;
for (int i=1;i<=n;i++){
cin>>s[i];
s[i] += s[i-1];
}
for (int len =2;len<=n;len++){//區間長度,從2開始,如果從1開始的話就只有一堆了不需要合併,先枚舉區間長度
for (int i=1;i+len-1<=n;i++){//再枚舉區間左端點,右端點爲i+len-1,要<-n;
int j = i+len-1;//右端點
f[i][j] = 1e8;
for(int k=i;k<j;k++){// i,j區間段
f[i][j] = min(f[i][j],f[i][k]+f[k+1][j] +s[j]-s[i-1]);
}
}
}
cout<<f[1][n]<<endl;
return 0;
}
題目來源: