题意

给一个长度为\(n\)的数组,你可以有两种操作

  • 将某一个数放置在数组开头
  • 将某一个数放置在数组结尾

问最小操作多少次可以得到一个非递减数列

(比\(F1\)难在\(n\)变大,且数组中元素可以有相同的)

分析

因为数组中的数很大,我们可以将其离散化然后操作,则\(a[i]\)为连续的整数,设\(tot\)种不同的数,则\(1\leq a[i] \leq tot\)

每个数最多操作一次,否则第一次可以不操作,那么我们就要找最多的不需要操作的数,如果不需要操作,则元素的位置不变,如果有这么一组不需要操作的数,我们可以发现,中间的数字是不能插进去的,所以这组数是在排序后仍相邻的数,则要找到最长的子序列,这个子序列在排序后仍然相邻,考虑以下几种情况

  • 这组数相同,则没有限制
  • 这组数中含有两种数,则要形如\(i,i,i,i+1,i+1\)这种形式,即排序后仍相邻
  • 这组数含有三种以上的数,即形如\(i,i,i+1,i+2,i+2,i+3\)这种形式,那么中间的数(\(i+1\),\(i+2\))一定是被取完了,否则其他的\(i+1\)或者\(i+2\)要插进去只能重新排序,与中间数字不能插进去不符,即这几个数并不是相邻,例如\(i,i+1,i+2,i+1\)这种序列,\(i,i+1,i+2\)并不满足条件,因为\(i+1\)并没取完

设\(dp[i][0]\)为只取相同的数且以\(a[i]\)为结尾所得到的最长子序列,\(dp[i][1]\)为\(a[i]\)还没取完且所得到的以\(a[i]\)为结尾最长子序列,\(dp[i][2]\)为\(a[i]\)取完且以\(a[i]\)为结尾所得到的最长子序列,我们用\(pos[i]\)表示数字\(i\)上次出现的位置,因为离散化了,所以数组可以满足,状态转移方程为(​\(r[a[i]]\)表示\(a[i]\)最后出现的位置,\(l[a[i]]\)表示\(a[i]\)最早出现的位置,\(num[a[i]]\)表示\(a[i]\)的个数,\(pos[a[i]]\)表示上一个\(a[i]\)出现的位置):

dp[i][0] = dp[pos[a[i]]][0] + 1;
dp[i][1] = max(dp[pos[a[i]]][1] + 1, max(dp[pos[a[i] - 1]][0] + 1, dp[pos[a[i] - 1]][2] + 1));
if (i == r[a[i]])
dp[i][2] = dp[l[a[i]]][1] + num[a[i]] - 1;
  • \(dp[i][0]\),方程表示上一个位置的\(a[i]\)接着取
  • \(dp[i][1]\),方程表示上一个\(a[i]\)接着取,或者上一个\(a[i]-1\)接着取,或者\(a[i]-1\)已经全部取完后接着取
  • \(dp[i][2]\),方程表示从最早出现的\(a[i]\)开始,后面都只取\(a[i]\)
#pragma GCC optimize(3, "Ofast", "inline")

#include <bits/stdc++.h>

#define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define ls st<<1
#define rs st<<1|1
#define pii pair<int,int>
#define rep(z, x, y) for(int z=x;z<=y;++z)
#define com bool operator<(const node &b)
using namespace std;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int maxn = (ll) 2e5 + 5;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
int T = 1;
int a[maxn], b[maxn];
int dp[maxn][3];
int l[maxn], r[maxn];
int pos[maxn], num[maxn]; void solve() {
int n;
cin >> n;
rep(i, 1, n)cin >> a[i], b[i] = a[i], dp[i][0] = dp[i][1] = dp[i][2] = 0, l[i] = r[i] = 0, num[i] = 0;
sort(b + 1, b + n + 1);
int tot = unique(b + 1, b + n + 1) - (b + 1);
rep(i, 1, n) {
a[i] = lower_bound(b + 1, b + tot + 1, a[i]) - b;
r[a[i]] = i;
if (!l[a[i]])
l[a[i]] = i, pos[a[i]] = i;
++num[a[i]];
}
int maxx = 1;
rep(i, 1, n) {
dp[i][0] = dp[pos[a[i]]][0] + 1;
dp[i][1] = max(dp[pos[a[i]]][1] + 1, max(dp[pos[a[i] - 1]][0] + 1, dp[pos[a[i] - 1]][2] + 1));
if (i == r[a[i]])
dp[i][2] = dp[l[a[i]]][1] + num[a[i]] - 1;
pos[a[i]] = i;
rep(j, 0, 2)maxx = max(maxx, dp[i][j]);
}
cout << n - maxx << '\n';
} signed main() {
start;
cin >> T;
while (T--)
solve();
return 0;
}

CodeForces 1367F2 Flying Sort (Hard Version)的更多相关文章

  1. Codeforces Round #650 (Div. 3) F1. Flying Sort (Easy Version) (离散化,贪心)

    题意:有一组数,每次操作可以将某个数移到头部或者尾部,问最少操作多少次使得这组数非递减. 题解:先离散化将每个数映射为排序后所对应的位置,然后贪心,求最长连续子序列的长度,那么最少的操作次数一定为\( ...

  2. codeforces 258div2 B Sort the Array

    题目链接:http://codeforces.com/contest/451/problem/B 解题报告:给出一个序列,要你判断这个序列能不能通过将其中某个子序列翻转使其成为升序的序列. 我的做法有 ...

  3. codeforces#1290E2 - Rotate Columns (hard version)(子集dp)

    题目链接: https://codeforces.com/contest/1209/problem/E2 题意: 给出$n$行和$m$列 每次操作循环挪动某列一次 可以执行无数次这样的操作 让每行最大 ...

  4. codeforces#1165 F2. Microtransactions (hard version) (二分+贪心)

    题目链接: https://codeforces.com/contest/1165/problem/F2 题意: 需要买$n$种物品,每种物品$k_i$个,每个物品需要两个硬币 每天获得一个硬币 有$ ...

  5. Codeforces 1326F2 - Wise Men (Hard Version)(FWT+整数划分)

    Codeforces 题目传送门 & 洛谷题目传送门 qwq 这题大约是二十来天前 AC 的罢,为何拖到此时才完成这篇题解,由此可见我是个名副其实的大鸽子( 这是我上 M 的那场我没切掉的 F ...

  6. codeforces 724B Batch Sort(暴力-列交换一次每行交换一次)

    题目链接:http://codeforces.com/problemset/problem/724/B 题目大意: 给出N*M矩阵,对于该矩阵有两种操作: (保证,每行输入的数是 1-m 之间的数且不 ...

  7. CodeForces 742B Batch Sort

    B. Batch Sort time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  8. quick sort java version

    import java.util.Random; public class test { public static void main(String[] args) { int[] arr= gen ...

  9. codeforces 340D Bubble Sort Graph(dp,LIS)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud  Bubble Sort Graph Iahub recently has lea ...

  10. Less or Equal CodeForces - 977C (sort+细节)

    You are given a sequence of integers of length nn and integer number kk. You should print any intege ...

随机推荐

  1. L2-001 紧急救援 (25 分)

    1.题目描述: 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当 ...

  2. 搭建自动化 Web 页面性能检测系统 —— 设计篇

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值.. 本文作者:琉易 liuxianyu.cn 页面性能对于用户体验.用 ...

  3. Microsoft R 和 Open Source R,哪一个才最适合你?

    由于微信不允许外部链接,你需要点击文章尾部左下角的 "阅读原文",才能访问文中链接. R 是一个开源统计软件,在分析领域普及的非常快. 在过去几年中,无论业务规模如何,很多公司都采 ...

  4. RIP动态路由协议配置实验

    项目背景 规划与配置接口 IP地址 AR1: [AR1-GigabitEthernet0/0/0]ip address 20.0.1.1 24 [AR1-GigabitEthernet0/0/1]ip ...

  5. MySQL中都有哪些锁?

    MySQL中都有哪些锁 为什么需要锁 在计算机系统中,锁(Lock)是一种同步机制,用于控制对共享资源的访问.它确保在任何给定时间内只有一个线程能够访问受保护的共享资源,从而避免了由并发访问导致的数据 ...

  6. CKS 考试题整理 (14)-启用API Server认证

    Context 由 kubeadm 创建的cluster 的kubernetes API 服务器,出于测试目的, 临时配置允许未经身份验证和未经授权的访问,授予匿名用户 cluster-admin 的 ...

  7. AGC019F Yes or No

    题意 有 \(N+M\) 个问题,其中有 \(N\) 个问题的答案是 YES,\(M\) 个问题的答案是 NO.当你回答一个问题之后,会知道这个问题的答案,求最优策略下期望对多少.答案对 \(9982 ...

  8. 10. Mybatis的缓存

    1. Mybatis 的一级缓存 ‍ 一级缓存是 SqlSession 级别的,通过同一个 SqlSession 查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问 , ...

  9. 如何通过数据warehouse更好地支持团队管理

    目录 引言 数据仓库是企业进行数据分析和决策的重要工具之一,能够帮助企业快速.准确地存储.管理和分析海量数据.但是,由于数据仓库系统的复杂性和广泛应用,如何通过数据 warehouse 更好地支持团队 ...

  10. 【HTML】Echart图表

    layui-echarts 简介 基于layui 实现的 echart 图表 Echart 官网 示例 Echart示例 下载Echart Echart下载 我们选择最下面的在线定制 我这里就按照它默 ...