zoukankan      html  css  js  c++  java
  • 【CF1481E】Sorting Books(动态规划)

    点此看题面

    • 给定(n)本书,每本书有一个颜色。
    • 每次操作你可以任选一本书移到最右边,问至少多少次操作能够让所有相同颜色的书都连在一起。
    • (nle5 imes10^5)

    动态规划

    当选中若干移到右边的书之后,我们是可以任意决定它们的顺序的。

    因此我们反向思考,去考虑留下来的书需要满足什么样的条件。

    然后就发现,除了最右边留下来的一种颜色,其余颜色的书必须要满足连成一块,且这种颜色的书必须完全保留。

    必须完全保留,也就意味着原本掺杂在这种颜色之间的所有书都必须右移。

    于是我们记录每种颜色最左边的书、最右边的书、书的数量,就可以把每种颜色看成一个区间。

    那么对于不在最右边的颜色,就是要满足选出权值总和尽可能大的完整区间,这种东西直接把所有区间按右端点排个序就可以愉快(DP)了。

    然后对于最右边的颜色,假设我们已经选出的所有区间最大的右端点为(R),那么我们显然会选取([R+1,n])中出现次数最多的书保留,这直接从后往前扫一遍,开桶维护预处理即可。

    代码:(O(nlogn))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 500000
    using namespace std;
    int n,a[N+5],f[N+5],Mn[N+5],Mx[N+5],tot[N+5],suf[N+5],cnt[N+5];
    struct Data
    {
    	int l,r,v;I Data(CI a=0,CI b=0,CI c=0):l(a),r(b),v(c){}
    	I bool operator < (Con Data& o) Con {return r<o.r;}//所有区间按右端点排序
    }s[N+5];
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define D isdigit(c=tc())
    		char c,*A,*B,FI[FS];
    	public:
    		I FastIO() {A=B=FI;}
    		Tp I void read(Ty& x) {x=0;W(!D);W(x=(x<<3)+(x<<1)+(c&15),D);}
    }F;
    int main()
    {
    	RI i;for(F.read(n),i=1;i<=n;++i) F.read(a[i]),!Mn[a[i]]&&(Mn[a[i]]=i),Mx[a[i]]=i;//维护每种颜色最左边的书、最右边的书
    	for(i=n;i;--i) suf[i]=max(++cnt[a[i]],suf[i+1]);//倒枚一遍,开桶维护每个后缀最多的书的本数
    	RI t=0;for(i=1;i<=n;++i) Mx[i]&&(s[++t]=Data(Mn[i],Mx[i],cnt[i]),0);sort(s+1,s+t+1);//建区间,然后排序
    	RI p=1;for(i=1;i<=n;f[i]=max(f[i],f[i-1]),++i) W(s[p].r==i) f[i]=max(f[i],f[s[p].l-1]+s[p].v),++p;//双指针维护DP
    	RI ans=0;for(i=1;i<=n;++i) ans=max(ans,f[i]+suf[i+1]);return printf("%d
    ",n-ans),0;//枚举最大的右端点统计答案
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    php 函数汇总
    php 图片base64编码生成dataurl和保存为图片
    bootstrap
    PHPWord
    js json排序
    UE用法
    判断移动端是苹果还是安卓,以及安卓版本
    shell终极操作
    LINUX yum用法
    jquery对checkbox的操作汇总
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF1481E.html
Copyright © 2011-2022 走看看