2017 多校4 Security Check

题意:

有\(A_i\)和\(B_i\)两个长度为\(n\)的队列过安检,当\(|A_i-B_j|>K\)的时候, \(A_i和B_j\)是可以同时过安检的,过安检必须按照队列的顺序,问你两个队列过完安检最少花费的时间

\(1<=n<=6e4\),

\(1<=A_i,B_i<=n\)

题解:

设\(f_{i,j}\)

表示仅考虑\(a[1..i]\)与\(b[1..j]\)时,最少需要多少时间。

若\(|a_i-b_j|>k\)

​,则\(f_{i,j}=f_{i-1,j-1}+1\)否则\(f_{i,j}=\min(f_{i-1,j},f_{i,j-1})+1\)

注意到后者只有\(O(nk)\)个,可以暴力DP,前者可以通过二分找到最大的\(t\),满足\(i,j\)往前\(t\)个均不冲突,然后再从某个后者状态转移过来。

时间复杂度\(O(nk\log n)\)。

这个\(dp\)就跟求最长公共子序列的dp一样,很容易想到\(O(n^{2})\)的做法,优化就不容易想到了,想到了也不知道如何实现

对于\(|A_i-B_j|<=K\)的时候 可以暴力\(dp\),

否则在\(i\)的左边找一个最接近\(i\)的\(t\) 满足\(|A_t-B_{j-i+t}|<=K\)

那么在\(t<p<=i\) 这一段 都是满足\(|A_p-B_{j-i+p}|>K\)他们同时过安检显然是最优的,直接算即可,这样下次有跳跃到了\(<=K\)的情况,所以只需要\(做dp\) 计算\(<=K\)的情况

如何找到这个\(t\)呢,开始我直接写了一发二分下标,WA,没仔细思考,这样二分下标不具有单调性。去网上看了看别人的写法,是把所有\(i-j\)差值为\(x\)而且\(|A_i-B_j|<=K\)的\(i\)存起来,然后去二分这个\(i\),好巧的做法,因为\(i,j\)一直往左走,走到\(t\),差值都是相同的,这样是可行的。

#include<bits/stdc++.h>
#define LL long long
#define P pair<int,int>
using namespace std;
const int N = 6e4 + 10;
int read(){
int x = 0;
char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
return x;
}
int n,k;
int a[N],b[N],pos[N];
vector<int> v[2 * N];///下标差值为x且绝对值小于等于k的 a_i的位置
int dp[N][22];
int Find(int i,int j){///i左边找到第一个x 使得abs(a[x] - b[j - i + x])<=k
int x = upper_bound(v[i - j + n].begin(),v[i - j + n].end(),i) - v[i - j + n].begin() - 1;
if(x < 0) return 0;
return v[i-j+n][x];
}
int dfs(int i,int j){
if(!i || !j) return i + j;
if(abs(a[i] - b[j]) <= k){
int &res = dp[i][a[i] - b[j] + k];
if(res != -1) return res;
return res = min(dfs(i-1,j),dfs(i,j-1)) + 1;
}
int x = Find(i,j);
return dfs(x,max(0,j - i + x)) + i - x;
}
int main(){ int T;
T = read();
while(T--){
n = read(),k = read();
for(int i = 1;i <= n;i++) a[i] = read();
for(int i = 1;i <= n;i++) b[i] = read(),pos[b[i]] = i;
for(int i = 0;i <= 2 * n;i++) v[i].clear();
for(int i = 1;i <= n;i++){
for(int j = max(1,a[i] - k);j <= min(a[i] + k,n);j++){
v[i - pos[j] + n].push_back(i);
}
}
memset(dp, -1, sizeof(dp));
printf("%d\n",dfs(n,n));
}
return 0;
}

2017 多校4 Security Check的更多相关文章

  1. HDU 6076 - Security Check | 2017 Multi-University Training Contest 4

    /* HDU 6076 - Security Check [ DP,二分 ] | 2017 Multi-University Training Contest 4 题意: 给出两个检票序列 A[N], ...

  2. hdu6097[二分+解析几何] 2017多校6

    /*hdu6097[二分+解析几何] 2017多校6*/ #include <bits/stdc++.h> using namespace std; ; struct node{ doub ...

  3. hdu6076 Security Check 分类dp 思维

    /** 题目:hdu6076 Security Check 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6076 题意:有两个队列在排队,每一次警察可以检 ...

  4. 2017 多校5 hdu 6093 Rikka with Number

    2017 多校5 Rikka with Number(数学 + 数位dp) 题意: 统计\([L,R]\)内 有多少数字 满足在某个\(d(d>=2)\)进制下是\(d\)的全排列的 \(1 & ...

  5. 2017 多校5 Rikka with String

    2017 多校5 Rikka with String(ac自动机+dp) 题意: Yuta has \(n\) \(01\) strings \(s_i\), and he wants to know ...

  6. 2017 多校4 Wavel Sequence

    2017 多校4 Wavel Sequence 题意: Formally, he defines a sequence \(a_1,a_2,...,a_n\) as ''wavel'' if and ...

  7. 2017 多校3 hdu 6061 RXD and functions

    2017 多校3 hdu 6061 RXD and functions(FFT) 题意: 给一个函数\(f(x)=\sum_{i=0}^{n}c_i \cdot x^{i}\) 求\(g(x) = f ...

  8. 2017 多校2 hdu 6053 TrickGCD

    2017 多校2 hdu 6053 TrickGCD 题目: You are given an array \(A\) , and Zhu wants to know there are how ma ...

  9. 2017 多校1 I Curse Myself

    2017 多校2 I Curse Myself(第k小生成树) 题目: 给一张带权无向连通图,该图的任意一条边最多只会经过一个简单环,定义\(V(k)为第k小生成树的权值和\),求出\(\sum_{k ...

随机推荐

  1. 【学时总结】◆学时·VIII◆ 树形DP

    ◆学时·VIII◆ 树形DP DP像猴子一样爬上了树……QwQ ◇ 算法概述 基于树的模型,由于树上没有环,满足DP的无后效性,可以充分发挥其强大统计以及计算答案的能力. 一般来说树形DP的状态定义有 ...

  2. Navicat-12.0.26的激活

    1.卸载掉早期版本,卸载干净,然后安装最新版Navicat(使用群文件中Iobit uninstaller8卸载) 2.安装完成后将破解补丁复制到安装目录下,运行破解补丁. 4.先patch,然后选择 ...

  3. 面试题 LazyMan 的Rxjs实现方式

    前言 笔者昨天在做某公司的线上笔试题的时候遇到了最后一道关于如何实现LazyMan的试题,题目如下 实现一个LazyMan,可以按照以下方式调用:LazyMan("Hank")输出 ...

  4. python flask学习第2天 URL中两种方式传参

    新创建项目   自己写个url映射到自定义的视图函数 在url中传递参数 app.py from flask import Flask app = Flask(__name__) @app.route ...

  5. 7-1 寻找大富翁 PTA 堆排序

    7-1 寻找大富翁 (25 分) 胡润研究院的调查显示,截至2017年底,中国个人资产超过1亿元的高净值人群达15万人.假设给出N个人的个人资产值,请快速找出资产排前M位的大富翁. 输入格式: 输入首 ...

  6. Android面试收集录17 Android进程优先级

    在安卓系统中:当系统内存不足时,Android系统将根据进程的优先级选择杀死一些不太重要的进程,优先级低的先杀死.进程优先级从高到低如下. 前台进程 处于正在与用户交互的activity 与前台act ...

  7. TouTiao开源项目 分析笔记19 问答内容

    1.真实页面预览 1.1.成果预览 首先是问答列表 然后每个item设置点击事件,进入问答内容列表 然后每一个问答内容也设置点击事件,进入问答详情 1.2.触发事件. 在WendaArticleOne ...

  8. java练习题——数组

    上述代码可以顺利通过编译,并且输出一个“很奇怪”的结果:[Ljava.lang.Object;@2a139a55 为什么会出现这种情况? 直接输出object的对象,系统会输出地址,如果想要输出其中的 ...

  9. Java线程和多线程(七)——ThreadLocal

    Java中的ThreadLocal是用来创建线程本地变量用的.我们都知道,访问某个对象的所有线程都是能够共享对象的状态的,所以这个对象状态就不是线程安全的.开发者可以通过使用同步来保证线程安全,但是如 ...

  10. cocos2d-x 3.0环境配置(转)

    cocos2d-x 3.0发布有一段时间了,作为一个初学者,我一直觉得cocos2d-x很坑.每个比较大的版本变动,都会有不一样的项目创建方式,每次的跨度都挺大…… 但是凭心而论,3.0RC版本开始 ...