动态规划基本模型(二)
区间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;
}

浙公网安备 33010602011771号