其他分享
首页 > 其他分享> > 戳气球问题

戳气球问题

作者:互联网

原题链接:  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