javaScript:动态规划实现回文数组算法题

javaScript:动态规划实现回文数组算法题


题目描述:
对于一个给定的正整数组成的数组 a[] ,如果将 a 倒序后数字的排列与 a 完全相同,我们称这个数组为“回文”的。
例如, [1, 2, 3, 2, 1] 的倒序是他自己,所以是一个回文的数组;而 [1, 2, 3, 1, 2] 的倒序是 [2, 1, 3, 2, 1] ,所以不是一个回文的数组。
对于任意一个正整数数组,如果我们向其中某些特定的位置插入一些正整数,那么我们总是能构造出一个回文的数组。

输入一个正整数组成的数组,要求你插入一些数字,使其变为回文的数组,且数组中所有数字的和尽可能小。输出这个插入后数组中元素的和。

例如,对于数组 [1, 2, 3, 1, 2] 我们可以插入两个 1 将其变为回文的数组 [1, 2, 1, 3, 1, 2, 1] ,这种变换方式数组的总和最小,为 11 ,所以输出为 11 。
输入描述:
输入数据由两行组成: 第一行包含一个正整数 L ,表示数组 a 的长度。 第二行包含 L 个正整数,表示数组 a 。 对于 40% 的数据: 1 < L <= 100 达成条件时需要插入的数字数量不多于 2 个。 对于 100% 的数据: 1 < L <= 1,000 0 < a[i] <= 1,000,000 达成条件时需要插入的数字数量没有限制。
输出描述:
输出一个整数,表示通过插入若干个正整数使数组 a 回文后,数组 a 的数字和的最小值。
题目来源牛客网

解析(欢迎指出错误或提出建议):
本题采用动态规划实现,为了能够清晰的弄清楚本题思路,也是为了给自己做笔记总结,先介绍下我对动态规划的简单理解:
动态规划是比较适合解决最优问题(并不是绝对),个人认为他的存在穷举的特点(但是他通过存储重复计算的值优化了穷举算法),这也是和贪心算法的一个明显的区别,怎样判断一个问题能否使用动态规划算法实现呢,一般来说需要同时满足两个条件
①最优子结构:要解决的最优问题可以分解成若干个最优子问题,并根据题目特点找出状态方程,与之联系的若干最优子问题参与状态方程计算得到当前最优问题的解,而最优子问题又可以根据此思想递归实现
②重叠子问题:递归时重复用到了相同的子问题,例如斐波那契数列问题的图解:
在这里插入图片描述
图中的f(3)与f(2)就重复用到了,这就是重复子问题

再回到本题,题目要求,任意给个数组,通过插值组成回文数组,组成方式肯定多种,题目要求出和最小的那种,首先这是个最优解问题,再来看他是否满足动态规划的两个条件,一最优子结构:以dp[i][j]存储子数组(第i个元素到第j个元素之间组成的子数组)通过插值组成和最小的回文数组的和,其实就是存储了子问题的最优解,那本题答案其实就是dp[0][length-1](length为题目所给的数组长度)的值,假设子问题已经是解决好了的问题,我要用子问题的解去表示dp[0][length-1],分析出来一般来说状态方程也分析出来了,根据题目回文数组的特点分析,设输入数组是arr,当arr[0]==arr[length-1]时,dp[0][length-1]=dp[1][length-2]+2arr[0](把dp[1][length-2]看做解决好了的子问题,他代表子数组arr.slice(1,length-1)能够组成的最小回文数组的和,因为arr[0]==arr[length-1],子数组arr.slice(1,length-1)组成最优解回文数组的情况下,也是arr数字组成最优回文数组的情况,其和自然是dp[1][length-2]+2arr[0]);当arr[0] != arr[length-1]时,说明此时还是需要插值构造的,构造也是要借助在子问题的基础上去构造,这是分解子问题的精髓,假设dp[1][length-1]和dp[0][length-2]这两个子问题是已经解决了的,为了方便说明,假设输入数字arr是[2,3,4],已经知道子数组[2,3]这个子问题的最优解是7(对应修改的数组是[2,3,2])

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值