一、定义
区间DP主要是把一个大区间拆分成几个小区间,在每个区间上进行DP,先求小区间的最优值,然后合并起来求大区间的最优值。
二、一般区间DP实现代码
memset(dp, 0x3f, sizeof(dp));//0x3f3f3f3f的每个字节都是0x3f,所以要把一段内存全部置为无穷大,我们只需要memset(a,0x3f,sizeof(a))。最精巧的无穷大常量取值是0x3f3f3f3f。
for (int i = 1; i <= n; i++)
dp[i][i] = 初始值;//初始化
for (int len = 2; len <= n; len++) //枚举区间长度
{
for (int i = 1;i<= n; i++) //枚举起点
{
int j=i+len-1; //区间终点
if(j>n) break; //越界结束
for(int k=i;k<j;k++) //枚举分割点,构造状态转移方程
{
dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+w[i][j]); //状态转移方程实现
}
}
}
三、个人理解
区间DP可能类似于贪心,都是把大问题化成小问题。但是不同在于,贪心是将大问题转化成小问题求每一步的最优解,每一步都会对下一步产生影响;而区间DP是将一个大区间分成多个小区间,求每一部分的最优解,每个区间求解的最优值都与其他区间无关。
区间DP就像背包一样,也有自己固定的解题模板,直接套用就可以,但是重点还是在于理解。
DP的思想在于在一个大的区间中插入分割点将达区间分解成多个小部分,在每个小区间上进行DP,再对每个区间的最优解进行比较,以求出整个区间的最优解。
区间DP一般需要写三重循环,分别控制区间长度,区间起点和在区间中插入的分割点,通过状态转移方程求解。
状态转移方程求解的是在不同的位置插入分割点所得的值中的最优解(最大值或最小值)。