Codeforces Round #699 E. Sorting Books(dp好题)

E. Sorting Books

题目传送门:

E. Sorting Books

题目大意:

书架上有n本书,每本书有自己的颜色ai,现在有一个操作是将一本书取出并放在书架的最右边。问最少需要多少次操作可以使颜色相同的书放在一起。

思路:

移动的很难考虑,那换个角度不防考虑最大化不移动书的数量。设f[i]表示i~n这些书中最大的不移动的数量。

1.如果i这个地方的书要动的话那么很简单f[i]=f[i+1]。

2.如果i这个地方不动的话,那么就是让i~n中所有颜色为a[i]的书都不动,动其他书。用R[x]表示颜色为x的书的最右边的那一个位置,L[x]为最左边的。那么显然 i ~ R[a[i]]之间其他颜色的书都是要动的,因为要让他们合并到一起,那么R[i]右边的书是否要动呢。我们可以想一下,当i != L[a[i]] 说明当前位置的左边还存在这个颜色的书,那要使他们合并,说明L[a[i]] ~ i中相同颜色的书其实是要移动到后面来的,所以R[i]右边的书也是需要移动的。

AC Code

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
int a[N];
int l[N],r[N],f[N],num[N];
int main()
{
    
    

    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
    
    
        scanf("%d",&a[i]);
        if(!l[a[i]]) l[a[i]]=i;
        r[a[i]]=i;
    }
    f[n+1]=0;
    for(int i=n;i>=1;i--)
    {
    
    
        num[a[i]]++;
        f[i]=f[i+1];
        if(i==l[a[i]]) f[i]=max(f[i],num[a[i]]+f[r[a[i]]+1]);
        else f[i]=max(f[i],num[a[i]]);    
    }
    printf("%d\n",n-f[1]);
    //system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Stevenwuxu/article/details/113763141