区间DP
直接以一道例题开始区间DP
原题链接 Acwing 282 石子合并
分析
对于本题,假设使用一维数组来设计状态和状态转移方程。如果使用正推的思想,不妨设f[i]
表示从第1堆石头合并到第i
堆石头的最小花费。设石堆的质量依次为1、4、2、5、3,那么:
f[1]
表示从第1堆石头合并到第1堆石头,f[1] = 1
f[2]
表示从第1堆石头合并到第2堆石头,f[2] = 1 + 4 = 5
- 当递推到
f[3]
的时候,表示从第1堆石头合并到第3堆石头,如果先合并前两堆,f[3]
尚且可以表示为f[2] + a[3]
,但如果先合并后两堆石头,很显然,表示f[3]
就显得极其麻烦了 - 由此得到结论,一维数组绝不是解决问题的最好方法
正确的设计
1、设计状态:
F[i][j]
:表示合并[i,j]
区间(第i
堆到第j
堆)范围内石子的最小花费
2、状态转移方程:
① 当i == j
时
当i == j时,F[i][j] = 0//合并第i堆到第i堆,即不用合并
② 当i != j
时,选取一个中间值k,将区间[i,j]
分为了两个部分,分别为区间[i,k]
和区间[k + 1,j]
,f[i][j]
等于合并左半区间所需要的代价与合并右半区间所需要的代价之和的最小值,再加上合并左右两个区间所需要的代价
F[i][j] = Min{F[i][k] + F[k + 1][j] + sum(i,j)}(i <= k <= j-1)
思考:k为什么要小于等j - 1
???
答:若k == j
,则k + 1 > j
,与题意矛盾
核心思想:
从小区间推导大区间
先算区间为1的情况,再算区间为2的情况,再算区间为len的情况 ……len的取值范围为[1,j-i+1]