动态规划-击爆气球 Burst Balloons
Posted timhy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划-击爆气球 Burst Balloons相关的知识,希望对你有一定的参考价值。
2018-10-03 19:29:43
问题描述:
问题求解:
很有意思的题目,首先想到的是暴力遍历解空间,当然也用到了memo,可惜还是TLE,因为时间复杂度确实有点过高了,应该是O(n!)。
Map<LinkedList, Integer> map = new HashMap<>(); public int maxCoins(int[] nums) { if (nums.length == 0) return 0; LinkedList<Integer> list = new LinkedList<>(); for (int i : nums) list.add(i); return helper(list); } private int helper(LinkedList<Integer> list) { if (list.size() == 1) return list.get(0); if (map.containsKey(list)) return map.get(list); int res = 1; ArrayList<Integer> arr = new ArrayList<>(list); for (int i = 0; i < list.size(); i++) { int pre = i == 0 ? 1 : arr.get(i - 1); int cur = arr.get(i); int next = i == arr.size() - 1 ? 1 : arr.get(i + 1); list.remove(i); res = Math.max(res, pre * cur * next + helper(list)); list.add(i, cur); } map.put(list, res); return res; }
本题给出了数据规模,基本已经提示了时间复杂度为O(n^3)左右比较合适。下面给出本题的标准解法,使用的是动态规划算法。
dp[i][j]:nums[i]到nums[j]能获得的最高分数
dp[i][j] = max(dp[i][k - 1] + nums[i - 1] * nums[k] * nums[j + 1] + dp[k + 1][j]) i <= k <= j // 每次挑选一个最后打爆的气球可以将问题规模下降
给原问题加上padding可以更方便编程。
public int maxCoins(int[] nums) { if (nums.length == 0) return 0; int n = nums.length; int[] numsPadding = new int[n + 2]; numsPadding[0] = 1; numsPadding[n + 1] = 1; for (int i = 1; i <= n; i++) numsPadding[i] = nums[i - 1]; int[][] dp = new int[n + 2][n + 2]; for (int len = 1; len <= n; len++) { for (int i = 1; i <= n - len + 1; i++) { int j = i + len - 1; for (int k = i; k <= j; k++) { dp[i][j] = Math.max(dp[i][j], dp[i][k - 1] + numsPadding[i - 1] * numsPadding[k] * numsPadding[j + 1] + dp[k + 1][j]); } } } return dp[1][n]; }
以上是关于动态规划-击爆气球 Burst Balloons的主要内容,如果未能解决你的问题,请参考以下文章
312. Burst Balloons - LeetCode
LeetCode 312. Burst Balloons(戳气球)
452. Minimum Number of Arrows to Burst Balloons扎气球的个数最少
leetcode 452. Minimum Number of Arrows to Burst Balloons 用最少数量的箭引爆气球(中等)
LeetCode | 0452. Minimum Number of Arrows to Burst Balloons用最少数量的箭引爆气球Python