区间动态规划的经典题,关于区间dp,状态定义是很显然的,定义f[i][j]表示把i~j这一区间合并花费的最小值,若i=j,则f[i][j]=0,若i≠j,则在i,j当中必定有一点k,使得i,j的区间先合并成i,k和k+1,j,然后合并成i,j.因此,对于每一对i,j,我们都枚举k,那么f[i][j]=min(f[i][k]+f[k+1][j]).然后我们预处理出合并的花费,相加即可。
另外,我们在循环的时候一定要注意阶段,状态,决策三者从外到内循环。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int sum[310],f[310][310],n; 6 int main() { 7 cin>>n; 8 memset(f,0x3f,sizeof(f)); 9 for(int i=1,x;i<=n;i++) { 10 cin>>x; 11 f[i][i]=0; 12 sum[i]=sum[i-1]+x; 13 } 14 for(int i=2;i<=n;i++) { 15 for(int l=1;l<=n-i+1;l++) { 16 int r=l+i-1; 17 for(int k=l;k<r;k++) 18 f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]); 19 f[l][r]+=sum[r]-sum[l-1]; 20 } 21 } 22 cout<<f[1][n]<<endl; 23 return 0; 24 }