leetcode专题训练312. Burst Balloons

解法1:
主要思路就是将戳气球的问题转化为往区间里加气球的问题,也就是将整个过程逆过来。solve(i, j)代表着(i, j)区间内所有气球全部被加好后,最多的coin个数。遍历(i,j)区间内第一个可以加的气球的位置mid,由于其他气球都还没加,所以此时加mid后coin个数为nums[mid]*nums[i]*nums[j],之后再以mid切割(i, j),分别计算solve(i, mid)和solve(mid, j)的值,便知道第一个加此mid位置时,最多能获得的coin数。遍历mid位置,取max,便可知道整体的能获取的最多coin个数。
就相当于遍历mid之后,将问题分为了两个子问题,将问题分治了

虽然和官方题解中思路一样,但是python过不了,而且官方题解的这个思路的python代码也过不了,但是c++就能过,猜测是因为c++本身耗时相对比python短
python代码:

class Solution:
    def maxCoins(self, nums: List[int]) -> int:
        result = 0
        nums = [1] + nums + [1]
        l = len(nums)

        if l == 3:
            return nums[1]

        d = [[0 for i in range(l)] for j in range(l)]

        def solve(i, j):
            # 这里的判断是j-1
            if i >= j-1:
                return 0
            if d[i][j] != 0:
                return d[i][j]

            tmpResult = 0
            for mid in range(i+1, j):
                tmpResult = max(tmpResult, nums[mid]*nums[i]*nums[j]+solve(i, mid)+solve(mid, j))
            d[i][j] = tmpResult
            return tmpResult

        return solve(0, l-1)

C++代码(可过):

const int maxl = 500;
int so[maxl+2][maxl+2]; // 结果
int nums_1[maxl+2]; 

class Solution {
public:
    int solve(int i, int j) {
        if(i >= j-1) {
            return 0;
        }
        if(so[i][j] != -1) {
            return so[i][j];
        }
        int tmpResult = 0;
        for(int mid = i+1; mid < j; mid++) {
            int tmp = nums_1[mid]*nums_1[i]*nums_1[j]+solve(i, mid)+solve(mid, j);
            if(tmp > tmpResult) {
                tmpResult = tmp;
            }
        }
        so[i][j] = tmpResult;
        return tmpResult;
    }

    int maxCoins(vector<int>& nums) {
        int l = nums.size();
        
        memset(so, -1, sizeof(so));

        // nums前后均加1
        nums_1[0] = 1;
        for(int i = 0; i < l; i++) {
            nums_1[i+1] = nums[i];
        }
        // 由于开头加了1,所以此处索引要为l+1
        nums_1[l+1] = 1;

        return solve(0, l+1);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值