• [CF1481E] Sorting Books


    前言

    也许是不够专注,这种方法都没想到。

    题目

    CF

    洛谷

    题目大意:见洛谷

    讲解

    我们需要意识到这样一个事情:最小化移动次数相当于最大化不移动的书的数量。

    这样就简单许多了。

    我们定义每种书的区间为该种书最左边的书的位置到最右边的位置。

    那么我们可以选择一些不相交的书,让它们不移动。而这个过程可以倒着 dp 实现。

    具体转移参考代码,很容易理解。

    代码

    它真的很短。

    //12252024832524
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define TT template<typename T>
    using namespace std;
    
    typedef long long LL;
    const int MAXN = 500005;
    int n;
    int a[MAXN],l[MAXN],r[MAXN],dp[MAXN],cnt[MAXN];
    
    LL Read()
    {
    	LL x = 0,f = 1;char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read(); 
    	for(int i = 1;i <= n;++ i) 
    	{
    		a[i] = Read();
    		if(!l[a[i]]) l[a[i]] = i;
    		r[a[i]] = i;
    	}
    	for(int i = n;i >= 1;-- i)
    	{
    		dp[i] = dp[i+1];
    		cnt[a[i]]++;
    		if(i == l[a[i]]) dp[i] = Max(dp[i],dp[r[a[i]]+1]+cnt[a[i]]);
    		else dp[i] = Max(dp[i],cnt[a[i]]);
    	}
    	Put(n-dp[1]);
    	return 0;
    }
    

    后记

    总感觉讲得不是很清楚。

  • 相关阅读:
    寄存器(内存访问)知识整理
    寄存器知识点
    汇编语言之实验一
    汇编语言基础知识的总结
    汇编语言之第五章至第八章知识汇总
    汇编实验之第八章数据处理的两个基本问题
    汇编语言之第七章更灵活的定位内存地址的方法
    汇编语言之实验九
    汇编语言之第六章包含多个段的程序
    汇编语言之第五章【BX】和loop指令
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/14924673.html
Copyright © 2020-2023  润新知