【区间dp-回文子序列-8-4】SH10 回文数组

描述

对于一个给定的正整数组成的数组 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 的数字和的最小值。

示例1

输入:

8
51 23 52 97 97 76 23 51

输出:

598

分析题目:【区间dp-回文子序列-8-1】leet 1312. 让字符串成为回文串的最少插入次数题目要求插入后回文串的长度最短,本题要求插入后回文数组和最少。同样,也可以按照上一题解决方案二。

dp[l][r]= s[l,r]变成回文字数组之后的 最少添加的和。则可以推出dp公式:

dp[l][r]=dp[l+1][r-1] 条件 nums[l]==nums[r]

dp[l][r]=Math.min(dp[l+1][r]+nums[l],dp[l][r-1]+nums[r]); 条件 nums[l]!=nums[r]

上面可以理解成:dp[l+1][r] 其实是 变成的回文数组的左边使用了nums[l], 所以变成的回文数组的右边也要补充一个对称的nums[l], 最小和增加了一个nums[l]=dp[l+1][r]+nums[l]

初始条件dp[l][r]=0,当 l == r。

题目要求回文数组的总和最小,就是原数组和+ 最少添加的和= sum(a)+dp[0][n-1]

代码:

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            int n = in.nextInt();
            int[] a = new int[n];
            int sum = 0;
            for (int i = 0; i < n; i++) {
                a[i] = in.nextInt();
                sum += a[i];
            }
            int ans = sum + minInsertions(a);
            System.out.println(ans);
        }
    }

    public static int minInsertions(int[] a) {
        int n = a.length;
        int[][] dp = new int[n][n];
        for (int r = 0; r < a.length; r++) {
            for (int l = r ; l >= 0; l--) {
                if (l == r) dp[l][r] = 0;
                else {
                    if (a[l] == a[r]) dp[l][r] = dp[l + 1][r - 1];
                    else dp[l][r] = Math.min(a[l] + dp[l + 1][r], dp[l][r - 1] + a[r]);
                }

            }
        }
        return dp[0][n - 1];
    }

相似题目:

【区间dp-回文子序列-7】leet 516. 最长回文子序列

【区间dp-回文子序列-8-1】leet 1312. 让字符串成为回文串的最少插入次数

【区间dp-回文子序列-8-2】添加最少的字符让字符串变为回文字符串

【区间dp-回文子序列-8-3】添加最少的字符让字符串变为回文字符串

算法笔试-动态规划系列 文章被收录于专栏

动态规划相关算法笔试题

全部评论

相关推荐

已oc&nbsp;云智断更了好几天,也有一些话想说,继续更新一篇云智timeline&nbsp;4.18&nbsp;一面&nbsp;半个小时后约二面&nbsp;4.21二面&nbsp;当晚&nbsp;约hr面&nbsp;4.23hr面&nbsp;4.30&nbsp;发offer之前美团的二面挂了,进入人才库,后面又被捞起来面试,4.30号&nbsp;美团又一面,现在还没出一面结果感觉也不报什么希望,就算一面过了,还有二面,我经不起深入拷打,唉,真的,好难五一躺平了五天,吃吃玩玩睡睡~还要担心毕业,科研更是难,唉暑期可能就到此为止了,后面没有时间在这个上面了,要抓紧时间做科研,为了后面能出去实习。大厂,秋招再见!!!有一些感慨:4.1是我的第一次面试,美团,面试的时候紧张到浑身发...
daisy9542:我今晚也是美团一面,已经第六次了。我也面了其他的,没拿到 offer。但我想开了,要按照自己的节奏来,找暑期转正然后秋招大杀四方并不是唯一的出路,其实还有很多选择的,有 0 实习最后秋招拿 offer 了,也有不选择互联网去国企的外企的,考编的,创业的。现在的失败不代表以后的路都是黑暗的,只不过可能运气还没降临到头上。所以现在要做的,就是放平心态,提升自己,通过面试了解到自己的优点和不足,争取下次机会来了能好好抓住
点赞 评论 收藏
分享
04-28 19:31
门头沟学院 Java
真烦好烦真烦:可恶的二手车贩子,居然对我们门头沟学院的人这么没礼貌
点赞 评论 收藏
分享
头像
03-20 22:00
重庆大学 Java
适彼乐土:“他们不行再找你” 最后的底牌吗?有点意思
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务