题目描述

给定一个数组arr,长度为n。代表排有分数的气球。 每打爆一个气球都能获得分数,假设打爆气球的分数为X,获得分数的规则如下:
      1)如果被打爆气球的左边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为L:如果被打爆气球的右边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为R.获得分数为L*X*R
      2)如果被打爆的气球的左边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为L:如果被打爆气球的右边所有气球都已经被打爆,获得分数为L*X。
      3)如果被打爆气球的左边所有的气球都已经被打爆:如果被打爆气球的右边有没被打爆的气球,找到离被打爆气球最近的气球。获得分数为X*R.
      4)如果被打爆气球的左边和右边所有的气球都已经被打爆。获得分数为X。
      目标是打爆所有气球,获得每次打爆的分数。通过选择打爆气球的顺序,可以得到不同的总分,请返回能获得的最大分数。

输入

3
3 2 5

输出

50

【思路】

很容易想到采取动态规划,由于问题计算依赖于子问题,一般的迭代思路有两大类:

①后面的计算依赖于前面的计算    如 dp[k]=>dp[k+1]                {k:0=>n}②问题的计算依赖于子问题的计算  如 dp[i,j]=max(dp[i,k]+dp[k,j])  {k:i=>j}

对于第一种,通常按照下标顺序迭代即可,可以细分为顺序迭代和反向滚动

对于第二种,通常按照研究子问题的规模不断扩大进行迭代 即: len: 0=>n

本问题,容易想到初始化研究dp[i][i] 然后扩大到dp[i][i+1]  继续dp[i][i+2]  .....  直到dp[0][n]为所求

错误思路:

dp[i][j]为击碎i到j所有气球的最大得分,对于第一个击碎的气球分类,划归为子问题

该思路错误在于,若研究先击碎哪一个vec[k]那么由于该气球被击碎,那么其两侧的计算讲耦合

(由于没有vec[k]先被被击碎,造成两侧相连,无法独立划分为子问题

正确思路:

dp[i][j]表示在其它灯完整情况下,击碎i=>j的最大得分。最后一个击碎的气球可能为k:i=>j
那么各种情况下的得分为:dp[i][k-1]+dp[k+1][j]+vec[i-1]*vec[k]*vec[j+1]由于k最后一个击碎,确保了两侧计算子问题的独立性,最后k的收益为vec[k] 乘 区间i,j外延伸

技巧点:

初始化vec(n+2,1)  其中vec[0]=1  vec[n+1]=1  用于辅助计算 因为a*1=a并且 dp[m][n]=0  当 m>n时候,因此在处理边界时可以统一纳入计算

代码:

int dp[502][502]={0};//dp[i][j]表示在其它灯完整的情况下(区间左右边界存在)  击碎区间i=>j的最大收益
int main()
{int n;cin>>n;vector<int> vec(n+2,1); //初始化vec[0]  vec[n+1]=1for(int i=1;i<=n;i++)cin>>vec[i];//单独打灭vec[i]的得分  (此时前后都有气球)for(int i=1;i<=n;i++)dp[i][i]=vec[i-1]*vec[i]*vec[i+1];for(int len=2;len<=n;len++)  //len为当前研究的数组长度{for(int i=1;i+len-1<=n;i++)  //区间为 【i,i+len-1】{for(int j=i;j<=i+len-1;j++)  //最后一个打灭的灯{dp[i][i+len-1]=max(dp[i][i+len-1],dp[i][j-1]+dp[j+1][i+len-1]+vec[j]*vec[i-1]*vec[i+len]);}   }}cout<<dp[1][n]<<endl;//最终所求}

Leetcode 击碎气球的最大分数相关推荐

  1. LeetCode 312.戳气球

    LeetCode 312.戳气球 有 n 个气球,编号为0 到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中. 现在要求你戳破所有的气球.戳破第 i 个气球,你可以获得 num ...

  2. unity 骨骼击碎_保证击碎$ 100挑战的创新策略

    unity 骨骼击碎 by Glenn Gonda 由Glenn Gonda 保证击碎$ 100挑战的创新策略 (A Creative Strategy Guaranteed to Crush the ...

  3. 【我与bug那些事】Vue 点击选项(有相应分数)实现分数相加【思路】

    点击选项(有相应分数)实现分数相加[思路] test 里面的da 为 相应分数~forEach 因为是要实现数值发生变化时,在页面上DOM同步更新~所以可能会用到计算属性

  4. 击碎“基因决定论”和“1万小时理论”认知误区!这本书告诉你怎么快速成长!

    有一本书一下子碾碎了普通人的两个认知误区. 第一个叫"基因决定论",认为天才就是天生的,普通人无论如何都无法追赶. 第二个叫"1万小时理论",虽然很多人奉这个规 ...

  5. Leetcode.312 戳气球

    题目链接 Leetcode.312 戳气球 题目描述 有 n个气球,编号为0到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums中. 现在要求你戳破所有的气球.戳破第 i 个气球,你可 ...

  6. RayFire for Unity制作一个可以被击碎的岩石

    RayFire for Unity制作一个可以被击碎的岩石 1.导入名字为Rock_05的Prefab 2.添加脚本 Rayfire Shatter,选择一个type,然点击Fragment,这时可以 ...

  7. 王劲卸任景驰CEO 无人驾驶梦被百度击碎

    ▼ 点击上方蓝字 关注网易智能 聚焦AI,读懂下一个大时代! 昨日晚间,网易智能第一时间获悉景驰科技创始人王劲卸任CEO的消息.目前,该消息已经得到了景驰其他高管的确认,称由于"个人家庭原因 ...

  8. Leetcode 312. 戳气球

    题目 首先必须要说明,这个题目的状态转移方程真的比较巧妙,所以说如果你看了题目之后完全没有思路恰恰是正常的.虽然最优答案不容易想出来,但基本的思路分析是我们应该力求做到的.所以本文会先分析一下常规思路 ...

  9. LeetCode 1770. 执行乘法运算的最大分数(DP)

    文章目录 1. 题目 2. 解题 1. 题目 给你两个长度分别 n 和 m 的整数数组 nums 和 multipliers ,其中 n >= m ,数组下标 从 1 开始 计数. 初始时,你的 ...

  10. LeetCode MySQL 1308. 不同性别每日分数总计(累加/变量/窗口函数)

    文章目录 1. 题目 2. 解题 1. 题目 表: Scores +---------------+---------+ | Column Name | Type | +--------------- ...

最新文章

  1. Linux 守护进程一
  2. java null转换jason_Java进阶知识,轻松理解Java泛型
  3. 利用IE8开发人员工具调试JavaScript脚本
  4. 如何循序渐进的学习javaScript呢,请听我慢慢道来!
  5. 意想不到的惊喜又来了 荣耀50系列或最高支持100W快充
  6. Linux下的Notepad++编辑器——Notepadqq
  7. 快速生成HTML结构语法(HTML、CSS)
  8. 存储空间的动态分配与释放
  9. mfc遍历指定文件夹下的所有文件并排序
  10. android camera textureview,Android SDK – camera2 – 在TextureView上绘制矩...
  11. VC2005字符集设置容易出错的问题!
  12. 计算机系统的软件配置要求高吗,ERP软件对电脑配置有什么要求?
  13. Addressable 增量包
  14. SegmentFault 社区访谈 | 有位公子在奇舞
  15. Intent 简介与详解
  16. python异步爬虫教程_tornado异步请求非阻塞|python爬虫|python入门|python教程
  17. Gitlab 登录报422错误,账号密码是对的?
  18. 爱签电子合同电子签章助力银行数智化发展
  19. java实现生成SVG格式的二维码
  20. 从非洲血库到热带雨林:为什么普惠联接是社会的数字化支点?

热门文章

  1. Vue项目-手机app瑞幸咖啡详解(全网最细) 从脚手架搭建到前后端数据交互(二)
  2. 自动驾驶赛道「孔雀东南飞」,何处安家?各有小算盘
  3. IDEA的粘贴板的一点问题
  4. async-supported的作用
  5. Androidnbsp;滑动屏幕效果学习之Gestur…
  6. 什么是信念?信任?信仰?
  7. 互联网金融指导意见落地 行业发展开始步入正轨
  8. 文字转化为二维码(数据加密)
  9. CIFAR10图像分类ResNet模型实战(pytorch)
  10. phpcms之 文件下载的页面