对数组进行排序所需的最少操作数

时间:2015-12-11 06:57:13

标签: arrays algorithm sorting greedy

我正在尝试从Codeforces中解决问题。它是通过将数组的元素移动到数组的开头或结尾来对数组进行排序。起初以为我认为它是增长最快的子序列,但在某些情况下它不起作用。例如,如果输入是4,1,2,5,3,则LIS为3,但问题的答案是将4移动到数组的末尾,然后将5移动到数组的末尾,这给了我们2.还有我我试图在这个LIS中的例子1,6,4,5,9,8,7,3,2是1,4,5,9,但问题的答案是1到2之间的7次移动。我得到了知道我应该使用贪婪的方法,但不能完全相关。有人可以帮助我吗?

2 个答案:

答案 0 :(得分:3)

我们可以看到,要对数组进行排序,每个元素只需要移动最多一个。

因此,为了最大限度地减少移动次数,我们需要找到未移动的元素的最大数量。这些元素是最长的连续序列,它是带有(a0, a1, ... an)的序列a(i + 1) = ai + 1

例如,

(4,1,2,5,3),最长的连续序列是(1,2,3)

(5,2,1,3,4),最长的连续序列是(2,3,4)

所以我们有代码:

int[]longest = new int[n + 1];
int result = 0;
for(int i = 0; i < n; i++){
    longest[data[i]] = longest[data[i] - 1] + 1;
    result = max (longest[data[i]] , result);
}

print "Minimum number of move is " + (n - result)

<强>解释

在代码中,我使用数组longest,其中索引ith存储最长的连续序列,该序列以value i结束。

所以,我们可以看到longest[i] = longest[i - 1] + 1

最长连续序列的结果是存储在longest数组中的最大值。

答案 1 :(得分:0)

我在比赛期间在Codeforces上解决了这个问题。好问题。

考虑&#39;最长的连续子序列 。答案是n- 最长的连续子序列
例子: 取1 2 3 7 5 6 4.最长的连续子序列是1 2 3 4. 现在您可以按特定顺序移动其余元素以使排序的数组始终。至少这是我直觉上的想法


以下是主要代码的片段:

    int n=in.readInt();
    int[] a=new int[n+1];
    int[] cnt=new int[n+1];
    int max=0;
    for(int i=0;i<n;i++)
        a[i]=in.readInt();
    for(int i=0;i<n;i++)
    {
        cnt[a[i]]=1+cnt[a[i]-1];
        max=Math.max(max,cnt[a[i]]);
    }
    out.printLine((n-max));


希望有所帮助!