题目链接:点击查看

题目大意:给出一个长度为 nnn 的序列,现在要求拆分成两个子序列,使得两个子序列的贡献之和最 。对于一个序列的贡献就是,去掉相邻且相同的字母后的长度,即 ∑i=1n[a[i]!=a[i−1]]\sum_{i=1}^{n}[a[i]!=a[i-1]]∑i=1n​[a[i]!=a[i−1]],其中 a[0]=0a[0]=0a[0]=0。

题目分析:首先预处理出对于每个位置 iii 后首次出现 aia_iai​ 的位置,即为 last[i]last[i]last[i],然后按照三个规则贪心即可:设 v1v1v1 为第一个序列的结尾位置,v2v2v2 为第二个序列的结尾位置,默认为 v1=v2=0v1=v2=0v1=v2=0,对于第 iii 个位置的数:

  1. 如果 a[i]=a[v1]a[i]=a[v1]a[i]=a[v1],那么将 a[i]a[i]a[i] 加在第一个序列后面的贡献为 000,所以应该加到第二个序列后
  2. 如果 a[i]=a[v2]a[i]=a[v2]a[i]=a[v2],根据规则 111 同理可得将 a[i]a[i]a[i] 加在第一个序列后面是更优的
  3. 如果 a[i],a[v1],a[v2]a[i],a[v1],a[v2]a[i],a[v1],a[v2] 互不相同,我们需要将 a[i]a[i]a[i] 加到 last[v1]last[v1]last[v1] 和 last[v2]last[v2]last[v2] 较小的那个序列后

规则一和规则二比较容易想到,主要是规则三,我先放上一组反例,假如第一个序列此时为 [1][1][1],第二个序列此时为 [2][2][2],剩余需要分配的原序列为 [3,2,2][3,2,2][3,2,2],如果将下一个 333 加入序列一的话,那么第二个 222,无论如何也无法起到贡献,所以应该将这个 333 加入到序列二中

感性理解一下规则三的话,就是 lastlastlast 更小的那个位置,可以更早的将当前新加入的数字代替掉,这样贡献肯定只会越来越大

实现就比较简单了

代码:

// Problem: D1. Painting the Array I
// Contest: Codeforces - Codeforces Round #700 (Div. 2)
// URL: https://codeforces.com/contest/1480/problem/D1
// Memory Limit: 512 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#define lowbit(x) x&-x
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f;
}
template<typename T>
inline void write(T x)
{if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;
int a[N],nt[N],last[N];
int main()
{#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int n;read(n);for(int i=1;i<=n;i++) {read(a[i]);last[i]=n+1;}last[0]=n+1;for(int i=n;i>=0;i--) {nt[i]=last[a[i]];last[a[i]]=i;}int ans=0,v1=0,v2=0;for(int i=1;i<=n;i++) {if(a[i]==a[v1]) {ans+=(a[i]!=a[v2]);v2=i;} else if(a[i]==a[v2]) {ans+=(a[i]!=a[v1]);v1=i;} else if(nt[v1]<nt[v2]) {ans++;v1=i;} else {ans++;v2=i;}}cout<<ans<<endl;return 0;
}

CodeForces - 1480D1 Painting the Array I(贪心)相关推荐

  1. CodeForces - 1480D2 Painting the Array II(dp)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,现在要求拆分成两个子序列,使得两个子序列的贡献之和最 小.对于一个序列的贡献就是,去掉相邻且相同的字母后的长度,即 ∑i=1n[a[i]! ...

  2. Codeforces G. Nick and Array(贪心)

    题目描述: Nick had received an awesome array of integers a=[a1,a2,-,an] as a gift for his 5 birthday fro ...

  3. 1480 D2. Painting the Array II(贪心)

    传送门 题目大意 把数组 a a a分成两个不相交的子数组 a 0 a^0 a0和 a 1 a^1 a1 要求 s e g ( a 0 ) seg(a^0) seg(a0)和 s e g ( a 1 ...

  4. Codeforces Round #700 (Div. 2) D2 Painting the Array II(最通俗易懂的贪心策略讲解)看不懂来打我 ~

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 整场比赛的A ~ E 6题全,全部题目超高质量题解链接: Codeforces Round #700 ...

  5. CF1479B Painting the Array

    CF1479B1 Painting the Array I CF1479B1 Painting the Array II 题意: 本题与 CF1480D2 的唯一区别是本题询问最大可能解. 给定一个数 ...

  6. Codeforces 437C The Child and Toy(贪心)

    题目连接:Codeforces 437C  The Child and Toy 贪心,每条绳子都是须要割断的,那就先割断最大值相应的那部分周围的绳子. #include <iostream> ...

  7. CodeForces 1514A Perfectly Imperfect Array

    CodeForces 1514A Perfectly Imperfect Array 题意: 给你n个数,是否存在一个数不是平方数 题解: 先开方,转int,判断是否等于平方 代码: #include ...

  8. codeforces#320(div2) D Or Game 贪心

    codeforces#320(div2) D  "Or" Game  贪心 D. "Or" Game time limit per test 2 seconds ...

  9. CodeForces - 1395D - Boboniu Chats with Du 贪心

    CodeForces - 1395D - Boboniu Chats with Du 贪心 题意:如果ai>ma_i>mai​>m,并且当天可以说话,则接下来ddd天不能说话.其余所 ...

最新文章

  1. c语言温度查表程序,温度计C语言程序.doc
  2. 《VMware、Citrix和Microsoft虚拟化技术详解与应用实践》一1.1 虚拟化概述
  3. 解决局域网IP冲突的问题
  4. java date 操作类_JAVA时间操作类常用方法汇总
  5. Hive环境的安装部署(完美安装)(集群内或集群外都适用)(含卸载自带mysql安装指定版本)...
  6. 无线网络连接无法停用
  7. 轮廓线重建:二维平行轮廓线重建理论和方法
  8. 又一次的Microsoft Visual C++ 10.0 is required (Unable to find vcvarsall.bat)
  9. VTK:图表之CreateTree
  10. jsapi支付签名_微信支付JSAPI:商户签名错误
  11. java poi 打开 保存_Java-Apache POI-在DB中读取和存储RTF内容
  12. 转载:GBDT算法梳理
  13. Velox将在Pangolin上启动其算法交易机器人,并计划推出更多DeFi解决方案
  14. ssh-keygen+ssh-copy-id无密码登录远程LINUX主机(转载)
  15. STM32F401RCT6最小系统原理图设计
  16. python 自动解析外文时间日期
  17. ept技术_Intel虚拟化技术——EPT、VPID
  18. Hadoop-HDFS详解与HA,完全分布式集群搭建(细到令人发指的教程)
  19. 一个简单的 jQuery 图片裁剪插件----cropper
  20. Python编程基础 第七章 编程练习 用户从键盘上输入一个字符串,如果该字符串的内容不是有效的数值,则输出invalid;如果是有效的数值,再判断其是否是整数,如果是整数则输出yes,否则输出no。

热门文章

  1. linux c 多线程socket编程,Linux多线程socket编程一些心得
  2. php获取当前整点时间_8.PHP的日期和时间
  3. Nacos源码更服务列表
  4. NioEventLoop 的实例化过程
  5. MyBatis 一级缓存与二级缓存的区别?
  6. 手写自己的MyBatis框架-核心对象
  7. Quartz源码总结
  8. TCP/IP的二层负载
  9. 方法引用_通过类名引用静态成员方法
  10. SpringBoot_数据访问-整合Druid配置数据源监控