说明
给定一正整数序列,例如:4,1,2,3,在不改变数的位置的条件下把它们相加,并且用括号来标记每一次加法所
得到的和。例如:((4+1)+ (2+3))=((5)+(5))=10。除去原数不4,1,2,3之外,其余都为中间结果
,如5,5,10,将中间结果相加,得到:5+5+10=20,那么数20称为此数列的一个代价,若得到另一种算法:(4+
((1+2)+3))=(4+((3)+3))=(4+(6))=10,数列的另一个代价为:3+6+10=19。若给出N个数,可加N-
1对括号,求出此数列的最小代价。
注:结果范围不超出longint.
输入格式
第一行为数N(1≤N≤200)
第二行为N个正整数,整数之间用空格隔开。
输出格式
输出仅一行,即为最少代价值。
样例
输入数据 1
4
4 1 2 3
Copy
输出数据 1
19
思路
直接用DP!!!!!!!
#include<bits/stdc++.h>
using namespace std;
//long long d=1e7,wl[]={9,2,5,5,4,5,6,3,7,6};
//long long f[101][100001];
//long long z[1000003],sd,g[1000003],o[1000300],uss[501][501],q,ev,egeg=0,wsws=0,ld[1000001];
//long long n,m,mo=1e9+7;
//long long s=10;
//long long sf=1,sg=s,sh=-1313333,tt=9e8,l,k,b1,b2,b3,b4;
//char iio;
struct ll{
long long a,b,c,d,e,k,x,y,z;
}v[102345];
bool qp(ll a,ll b){
return a.a<b.a;
}
long long mo=1e9+7,f[1005][1005],ld[100005],lk=0,n,m,z[1045];
int main(){
cin>>n;
memset(f,31,sizeof(f));
for(int i=1;i<=n;i++){
cin>>z[i];
ld[i]=z[i];
ld[i]+=ld[i-1];
f[i][i]=0;
}
for(int i=n-1;i>=1;i--){
for(int j=i+1;j<=n;j++){
for(int k=i;k<=j-1;k++){
f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+(ld[j]-ld[i-1]));
}
}
}
cout<<f[1][n]<<endl;
return 0;
}