有点理解了进阶指南上说的”阶段,状态和决策“
/* 区间dp的基础题: 以区间长度[2,n]为阶段,枚举该长度的区间,状态dp[l][r]表示合并区间[l,r]的最小费用 状态转移方程dp[l][r]=sum[r]-sum[l]+min(dp[l][k]+dp[k+1][r]),其中k是决策 */ #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; int n,sum[150],a[150],dp[150][150]; int main(){ while(scanf("%d",&n)==1){ for(int i=1;i<=n;i++)scanf("%d",&a[i]); memset(dp,0x3f,sizeof dp); for(int i=1;i<=n;i++){//初始状态 dp[i][i]=0; sum[i]=sum[i-1]+a[i]; } for(int len=2;len<=n;len++)//阶段 for(int l=1;l<=n-len+1;l++){//状态;左端点 int r=l+len-1;//状态,右端点 for(int k=l;k<r;k++)//决策 dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]); dp[l][r]+=sum[r]-sum[l-1]; } printf("%d ",dp[1][n]); memset(dp,0,sizeof dp); for(int len=2;len<=n;len++) for(int l=1;l<=n-len+1;l++){ int r=l+len-1; for(int k=1;k<r;k++) dp[l][r]=max(dp[l][r],dp[l][k]+dp[k+1][r]); dp[l][r]+=sum[r]-sum[l-1]; } printf("%d ",dp[1][n]); } }