時間限制:2.0s 記憶體限制:256.0mb
提交此題
問題描述
在一條直線上有n堆石子,每堆有一定的數量,每次可以將兩堆相鄰的石子合併,合併後放在兩堆的中間位置,合併的費用為兩堆石子的總數。求把所有石子合併成一堆的最小花費。
輸入格式
輸入第一行包含乙個整數n,表示石子的堆數。
接下來一行,包含n個整數,按順序給出每堆石子的大小 。
輸出格式
輸出乙個整數,表示合併的最小花費。
樣例輸入
5 1 2 3 4 5
樣例輸出
33 資料規模和約定
1<=n<=1000, 每堆石子至少1顆,最多10000顆。
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define mem(a,n) memset(a,n,sizeof(a))
#define rep(i,a,n) for(int i=a;i#define pb push_back
typedef
long
long ll;
const
int inf=0x3f3f3f3f;
const
double pi=3.1415926;
const
int n=1e3+5;
int sum[n],dp[n][n];
/**思路:貪心法只是區域性最優, (區間dp)全域性最優 通過區域性最優求解
dp[i][j]= 0 ; i = j時
min(dp[j][j],dp[i][k]+dp[k+1][j) + (sum[j] - sum[i-1]); i != j時
**/int main()
for(int r=2; r<=n; r++)///求區間長度r的最小值
dp[i][j]+=(sum[j]-sum[i-1]);///放在迴圈內部會tle}}
printf("%d\n",dp[1][n]);
}return
0;}
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define mem(a,n) memset(a,n,sizeof(a))
#define rep(i,a,n) for(int i=a;i#define pb push_back
typedef long long ll;
const int inf=0x3f3f3f3f;
const double pi=3.1415926;
const int n=1e3+5;
int sum[n],dp[n][n],p[n][n];
/**思路:貪心法只是區域性最優, (區間dp)全域性最優 通過區域性最優求解
dp[i][j]= 0 ; i = j時
min(dp[j][j],dp[i][k]+dp[k+1][j) + (sum[j] - sum[i-1]); i != j時
**/int main()
for(int r=2; r<=n; r++)///求區間長度r的最小值
}dp[i][j]+=(sum[j]-sum[i-1]);}}
printf("%d\n",dp[1][n]);
}return 0;
}
石子合併 四邊形優化
動態規劃的經典題目,在遇到狀態轉移方程像min w i k w k 1 j m i j 的時候就可以使用考慮使用四邊形優化。在i i j j 的條件滿足的情況下,有w i j w i j w i j w i j 那麼就可以使用s i j 同時s i j 又有單調遞增性 並沒有仔細看 以後有時間一定補...
石子合併 四邊形優化
description 在乙個操場上擺放著一排n堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。試設計乙個演算法,計算出將n堆石子合併成一堆的最小得分。input 第一行是乙個數n。以下n行每行乙個數a,表示石子數目。outpu...
區間DP入門 四邊形優化
區間dp,顧名思義,求區間最值問題。通過合併小區間最優解來更新大區間,然後逐漸更新出答案。要求解在乙個區間上的最優解,那麼就要把這個區間分割成乙個個小區間,求解每個小區間的最優解,再合併小區間得到大區間。所以在 實現上,先列舉區間長度len為每次分割成的小區間長度 由短到長不斷合併 內層列舉該長度下...