戳气球问题
作者:互联网
原题链接: https://leetcode-cn.com/problems/burst-balloons/
问题描述
有 n 个气球,编号为0 到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中。
现在要求你戳破所有的气球。戳破第 i 个气球,你可以获得 nums[i - 1] * nums[i] * nums[i + 1] 枚硬
币。 这里的 i - 1 和 i + 1 代表和 i 相邻的两个气球的序号。如果 i - 1或 i + 1 超出了数组的边界,
那么就当它是一个数字为 1 的气球。求所能获得硬币的最大数量。
解决思路
首先应该明确此类题目可以使用动态规划方法求解。那么我们去寻找dp状态转移方程。
考虑双开区间 (i , j)
1. i - j <=1 ,此时i、j区间内无气球可以戳破。
2. 在 i - j >1 时,考虑最后戳破的气球下标是k,有 i<k<j ,这是k的左右一定是 i 和 j,则
sum = nums[i] * nums[k] * nums[j];
sum+=dp[i][k] + dp[k][j] 是这一次的取值得到的硬币数。
3. 考虑到边界情况,我们可以对num进行扩展,将首位补1。
代码实现
class Solution {
public:
int maxCoins(vector<int>& nums) {
//注意,这里n是size + 2
int n = nums.size() + 2;
vector<int> data(n, 0);
//数据准备
data[0] = data[n - 1] = 1;
for (int i = 1; i < n - 1; i++)
{
data[i] = nums[i - 1];
}
vector<vector<int>> dp(n, vector<int>(n, 0));
//因为扩充和开区间缘故, level从2开始
int level = 2;
for (; level < n; level++)
{
for (int i = 0; i < n - level; i++)
{
int j = i + level;
for (int k = i + 1; k < j; k++)
{
dp[i][j] = max(dp[i][j], dp[i][k] + dp[k][j] + data[i] * data[k] * data[j]);
}
}
}
return dp[0][n - 1];
}
};
思考
这类问题一般难点在于状态转移方程,注意最外层循环使用level。
标签:level,int,nums,问题,data,气球,dp 来源: https://blog.csdn.net/qq_37936990/article/details/118934560