引言
戳气球问题是dp问题中的一道经典问题,难度在于逆向的思维和复杂的dp遍历方法。
题目链接添加链接描述
题目
设计状态和转移方程
首先如果是正向思维,其实很难求解。难点在于定义状态,如何定义第i个和第j个气球已经被戳破的状态。我首先想到的方法是数位dp的方法,设置有n个二进制数字,初始化全1,如果扎破了该位就置0,这样是可以定义状态的。但是这道题目的n很大,很难进行实现。
因此第一个难点出现了,考虑逆向的思维,开始添加气球。按照什么样的顺序添加气球才能够得到最大的金币。因此我们可以考虑这么一个子问题,假设最后一个戳破的气球是K号气球,则得到这个状态的的前提是,K气球的两侧气球全部都被戳破了已经。
因此我们定义状态dp[left][right]
为开区间 ( l e f t , r i g h t ) (left, right) (left,right)中戳破所以气球的最大收益,这里我们需要对原数组增补两个1在头尾。
因此可以得到转移方程dp[left][right] = dp[k][right] + dp[left][k] + nums[left]*nums[right]*nums[k]
,其中,k在[left+1, right-1]
之间遍历,选择最大值。
遍历方法
dp问题还有一个难点在于状态转移所依赖的状态必须被提前计算出来。从上面的转移方程可以看到,dp[left][right]
需要依赖dp[left][i]
和dp[i][right]
。参考labuladong的图。