---恢复内容开始---
算法提高 合并石子
时间限制:2.0s 内存限制:256.0MB
问题描述
在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位置,合并的费用为两堆石子的总数。求把所有石子合并成一堆的最小花费。
输入格式
输入第一行包含一个整数n,表示石子的堆数。
接下来一行,包含n个整数,按顺序给出每堆石子的大小 。
接下来一行,包含n个整数,按顺序给出每堆石子的大小 。
输出格式
输出一个整数,表示合并的最小花费。
样例输入
5
1 2 3 4 5
1 2 3 4 5
样例输出
33
数据规模和约定
1<=n<=1000, 每堆石子至少1颗,最多10000颗。
#include <iostream> #include <cstdio> #include <vector> #include <queue> #include <map> #include <stack> #include <cstring> #include <algorithm> #include <cstdlib> #define FOR(i,x,n) for(long i=x;i<n;i++) #define ll long long int #define INF 0x3f3f3f3f3f3f3f3f #define MOD 1000000007 #define MAX_N 50005 using namespace std; int m[1005][1005]; int a[1005]; int main() { //freopen("input1.txt", "r", stdin); //freopen("data.out", "w", stdout); int N; ll sum=0; scanf("%d",&N); FOR(i,0,N){ scanf("%d",&a[i]); m[i][i]=0; //sum+=a[i]; } FOR(i,1,N){ FOR(jj,0,N-i){ int j=jj+i; int minn=INF; int s=0; FOR(k,jj,j){ s+=a[k]; int t=m[jj][k]+m[k+1][j]; if(t<minn){ minn=t; } } s+=a[j]; m[jj][j]=minn+s; } } printf("%d",m[0][N-1]); //fclose(stdin); //fclose(stdout); return 0; }
---恢复内容结束---