获得最长凸子序列的问题

时间:2019-03-24 21:17:47

标签: java algorithm dynamic-programming

如果对于2到2之间的每个整数i,如果X [i + 1]-X [i]> X [i]-X [i-1],则整数序列X [1..m]是凸的。 m-1。

for (int i = 1; i < list.size(); i++) {
            for (int j = 0; j < list.size(); j++) {
                dp[i][j] = 2;
                for (int k = 0; k < j; k++) {
                    if (dp[j][k] + 1 > dp[i][j] && ((list.get(i) + list.get(k)) > (list.get(j) * 2))) {
                        dp[i][j] = dp[j][k] + 1;
                    }
                    len = Math.max(len, dp[i][j]);
                }
            }
        }

我发现有一种模式,给定X [1..m],通过让Y [i] = X [i]-X [i-1]来定义Y [2..m]。因此,Y是由X的连续项之间的差组成的序列。当且仅当序列Y在增加时,序列X是凸的。 我想知道有什么方法可以得到像 A = [0,3,7,8,13] 这样的子序列,那么最长的凸子序列是[0,3,7,13 ] 。 预先感谢。

1 个答案:

答案 0 :(得分:1)

您是对的,可以通过动态编程解决此问题。通常的想法是存储每个可能的有效凸子序列,这些子序列以原始数组的每个元素结尾并具有特定的最大连续元素差,然后使用所有先前的条目来构造下一个子序列。

更具体地说,构造一个2D矩阵,该矩阵将以特定index结尾的最长凸序列存储到原始数组A中,并将连续项之间的最大差异最多存储diff。因此,dp[3][11]将给出最长的凸子串,该子串以A的第3个元素结尾,并且不包含大于11的连续差。

使用此数组中的先前条目,我们可以为原始数组的第k个元素构造行k。只需遍历每个先前的行j,然后将A[k]连接到dp[j][diff]处的每个序列,即可获得diff范围内的[0, A[k]-A[j])。将此新序列存储在dp[k][diff+1]中。每当dp[k][diff+1]diff发生冲突时,请保留两个序列中的较长者。

冲洗并重复此过程,直到A中的element元素行为止。然后,从每行的最长子序列中取出最长的序列。最长的子序列将始终是每行中的最后一个非空元素,因此只需向后迭代每行,并获取最长的行。这将是您最长的凸子序列。