312. 戳气球

问题描述:

有 n 个气球,编号为0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中。
现在要求你戳破所有的气球。每当你戳破一个气球 i 时,你可以获得 nums[left] * nums[i] * nums[right] 个硬币。 这里的 left 和 right 代表和 i 相邻的两个气球的序号。注意当你戳破了气球 i 后,气球 left 和气球 right 就变成了相邻的气球。
求所能获得硬币的最大数量。
示例:
输入: [3,1,5,8]
输出: 167
解释: nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
coins = 167

若气球编号为0 到 n-1,当最后戳破气球k时,此时数组里仅剩第k个气球,因此得到的硬币数应该为nums[-1]*nums[k]*nums[n]。设从i到j编号的气球得到的最大硬币数为dp[i][j].
那么得到的总硬币数应该是dp[i][k]+dp[k][j]+nums[-1]*nums[k]*nums[n]。若要找到最大的硬币数,则需要找到最大的分割点k。
即可得到转移方程:
dp[i][j] = max(dp[i][k]+dp[k][j]+nums[-1]*nums[k]*nums[n])
由于计算dp[i][j]需要(i,j)左侧和下方的结果,因此需要斜向遍历。
具体实现如下:

class Solution {
public:
    int maxCoins(vector& nums) {
        nums.insert(nums.begin(), 1);
        nums.push_back(1);
        int n = nums.size();
        vector t(n, 0);
        vector> dp(n, t);
        //dp[i][j] = max(dp[i][k] + dp[k][j] + nums[i] * nums[k] * nums[j])
        for(int len=2;len

与此类似的矩阵乘法问题。

问题描述:

给定n个矩阵:A1,A2,...,An,其中Ai与Ai+1是可乘的,i=1,2...,n-1。确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。输入数据为矩阵个数和每个矩阵规模,输出结果为计算矩阵连乘积的计算次序和最少数乘次数。

同样需要找到合适的分割点k,来得到最小值。
其转移方程为:
dp[i][j] = min(dp[i][k]+dp[k][j]+p[i-1]p[k]p[j]
其中,p[i-1]是第i个矩阵的行数,p[j]是第j个矩阵的列数。

你可能感兴趣的:(312. 戳气球)