原始题目
1592: 石子归并
- Time Limit: 1 Sec
- Memory Limit: 128 Mb
- Submitted: 896
- Solved: 421
Description
现在有\(n\)堆石子,第\(i\)堆有\(a_i\)个石子。现在要把这些石子合并成一堆,每次只能合并相邻两个,每次合并的代价是两堆石子的总石子数。求合并所有石子的最小代价。
第一行包含一个整数$T ( T 50) $ ,表示数据组数。
每组数据第一行包含一个整数$ n ( 2 n 100 ) $,表示石子的堆数。
第二行包含\(n\)个正整数$ a_i ( a_i 100)$,表示每堆石子的石子数。
Output
每组数据仅一行,表示最小合并代价。
2
4
1 2 3 4
5
3 5 2 1 4
Sample Output
19
33
Hint
Source
国防科学技术大学第十八届银河之光文化节ACM程序设计竞赛初赛
题目大意
如题
解题思路
解题代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #include <vector> #include <queue> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm>
#define ms(i,a) memset((i),(a),sizeof(i)) #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define pb push_back #define mp make_pair #define np next_permutation #define all(x) x.begin(),x.end() #define fi first #define se second #define SZ(x) ((int)(x).size()) #define INF 0x3f3f3f3f
using namespace std;
int n,t,m;
int dp[105][105],sum[105]; void initial(){ rep(i,1,n+1){ rep(j,1,n+1){ if(i==j) dp[i][j]=0; else dp[i][j]=INF; } } } int main() { ios::sync_with_stdio(false); cin>>t; while(t--) { cin>>n; sum[0]=0; rep(i,1,n+1){ cin>>m; sum[i]=sum[i-1]+m; } initial(); for(int len=1; len<n; len++) { for(int i=1; i+len<=n; i++) { int j=i+len; for(int k=0; i+k<j; k++) dp[i][j]=min(dp[i][j],dp[i][i+k]+dp[i+k+1][j]+sum[j]-sum[i-1]); } } cout<<dp[1][n]<<endl; } return 0; }
|
收获与反思