#include<stdio.h>
using namespace std;
int n,w[110],f[110][110];
int mmin(int a,int b){
return a<b?a:b;
}
int summ(int a,int b){
int ssum=0;
for(int k=a;k<=b;k++) ssum+=w[k];
return ssum;
}
int d(int i,int j){
if(f[i][j]>0) return f[i][j];
else if(i==j) return f[i][j]=0;
else{
int minn=1000000;
for(int k=i;k<j;k++){//注意k<j而不是k<=j!
int o=d(i,k)+d(k+1,j)+summ(i,j);//注意第二段从k+1开始
minn=o<minn?o:minn;
}
return f[i][j]=minn;
}
}
int main(){
freopen("1048.in","r",stdin);
freopen("1048.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++) cin>>w[i];
cout<<d(1,n);
return 0;
}
题解:记忆化搜索,状态转移方程 d(i,j)=min(d(i,k)+d(k+1,j)+summ(i,j))注意第二段从k+1开始,边界d(i,j)={0|i==j}.