【Leetcode】312. 戳气球(DP + 分治)

题目:312

题意:有N个气球,要求你戳破所有的气球,每戳破一个,你可以获得nums[left]*nums[i]*nums[right]个硬币,注意戳破一个气球后相邻顺序会改变。求戳破所有气球所能获得的最大硬币数量

题解:

DP + 分治,主要是想分解为重叠子问题,但是如果简单考虑一下,先随机选择一个气球,然后求左右两边的两个子问题,但是左右两边并不是独立的子问题,即左边的顺序会影响右边的计算结果。所有我们可以继续想一下,如何将左右两边划分为两个独立的子问题,于是我们可以得到如下结论:

left 和 right 相互独立  <=>  k 点为对于N的分割时,最后一个被踩破的气球。

这样的话我们就可以整体DP+局部分治进行求解了。

代码:

class Solution {
public:
	int maxCoins(vector<int>& nums) {
		int n = nums.size(); //新构造数组的大小
		vector<int> arr(nums);
		arr.insert(arr.begin(), 1);
		arr.insert(arr.end(), 1);

		vector< vector<int> > dp(n + 2, vector<int>(n + 2, 0));  //边界dp[i][i+1] == 0

		//状态转移方程
		for (int len = 2; len < n + 2; ++len)
			for (int i = 0; i < n + 2 - len; ++i)
				for (int k = i + 1; k < i + len; ++k)
					dp[i][i + len] = max(dp[i][i + len], dp[i][k] + dp[k][i + len] + arr[i] * arr[k] * arr[i + len]);

		return dp[0][n + 1];
	}
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值