动态规划基本模型(二)
区间DP
例题:石子合并;
先使用a[i]初始化每个石子的价值
合并n个则需要先合并n-1个 子问题就是合并1~n个的最小值
则合并l长度个的最小值为合并左结点到右结点的最小值;
子问题为每个区间的合并最小值;
使用k枚举每个区间;
则有dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+合并这两段的和)
使用sum[i]初始化每段的价值;
for (int i=1;i<=n;i++)
sum[i]=sum[i]+a[i-1];
则有两段合并的和为右侧结点的sum减去左侧结点的sum
即sum[j]-sum[i-1];
输出dp[1][n]即可
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; int n; int a[1001],dp[1001][1001],sum[1001]; int main () { cin>>n; for (int i=1;i<=n;i++) cin>>a[i]; for (int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]; for (int l=1;l<=n;l++) { for (int i=1;i<=l;i++) { int j=i+l-1; dp[i][j]=1239813; for (int k=i;k<=j;k++) { dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]); } } } cout<<dp[1][n]; return 0; }