zoukankan      html  css  js  c++  java
  • leetcode 戳气球

    有 n 个气球,编号为0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中。

    现在要求你戳破所有的气球。每当你戳破一个气球 i 时,你可以获得 nums[left] * nums[i] * nums[right] 个硬币。 这里的 left 和 right 代表和 i 相邻的两个气球的序号。注意当你戳破了气球 i后,气球 left 和气球 right 就变成了相邻的气球。

    求所能获得硬币的最大数量。

    说明:

    • 你可以假设 nums[-1] = nums[n] = 1,但注意它们不是真实存在的所以并不能被戳破。
    • 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100

    示例:

    输入: [3,1,5,8]
    输出: 167 
    解释: nums = [3,1,5,8] --> [3,5,8] -->   [3,8]   -->  [8]  --> []
         coins =  3*1*5      +  3*5*8    +  1*3*8      + 1*8*1   = 167


    class Solution {
        public int maxCoins(int[] nums) {
            int len = nums.length;
            int[] langarr = new int[len+2];
            langarr[0] = 1;
            for (int i = 0, j = 1; i < len; i++, j++) langarr[j] = nums[i];
            len = langarr.length;
            int[][] dp = new int[len][len];
            langarr[len-1] = 1;
            for (int i = 2; i < len; i++) {
                for (int j = 0; j+i < len; j++) {
                    for (int k = j+1; k < j+i; k++) {
                        dp[j][j+i] = Math.max(dp[j][j+i], dp[j][k]+dp[k][j+i]+langarr[j]*langarr[k]*langarr[j+i]);
                    }
                }
            }
            return dp[0][len-1];
        }
    }

    dp[i][j]的含义是 第i个气球到第j个气球(不包含i,j) ,最好的扎法能得多少分。

    dp[j][j+i] = Math.max(dp[j][j+i], dp[j][k]+dp[k][j+i]+langarr[j]*langarr[k]*langarr[j+i]);

    以上是最精华的递推公式,这种属于分治思想,分治的动态规划题 dp为二维的时候,从短的长度到长的长度去渗透,
    k的含义是,假设k是最后一个扎破的气球, 这个想法最关键(自己想到了分治,但是总是感觉左右会有依赖没法分),也是这道题最难想到的点,最后一个扎破的气球的左边和右边是完全没有依赖关系的,可以分别运算的部分。
    如果k是最后一个扎破的,那么最后一次的得分也可以得出。
  • 相关阅读:
    共享纸巾更换主板代码分析 共享纸巾主板更换后的对接代码
    Python Django Ajax 传递列表数据
    Python Django migrate 报错解决办法
    Python 创建字典的多种方式
    Python 两个list合并成一个字典
    Python 正则 re.sub替换
    python Django Ajax基础
    Python Django 获取表单数据的三种方式
    python Django html 模板循环条件
    Python Django ORM 字段类型、参数、外键操作
  • 原文地址:https://www.cnblogs.com/tobemaster/p/9446518.html
Copyright © 2011-2022 走看看