ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

戳气球问题

2021-07-20 14:58:13  阅读:222  来源: 互联网

标签:level int nums 问题 data 气球 dp


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有