题目大意

    上下有两个长度为n、位置对应的序列A、B,其中数的范围均为1~n。若abs(A[i]-B[j]) <= 4,则A[i]与B[j]间可以连一条边。现要求在边与边不相交的情况下的最大的连边数量。n <= 10^5。

  在Gold里,此题的数据范围是1000,我们完全可以用简单的最长公共连续子序列的DP方法来做。

  范围大了之后,可以观察到对于一个数A[i],它所能转移的状态最多只有9个,那么就可以顺序扫描A数组,设F[i][j]表示当前连得最后一条边为(A[i],B[to[i][j]])的最优解。to[i][j]即A[i]能转移到的B[i]的位置(顺序从小到大)。建立一棵线段树,表示最后连的边中的数B在B数组的位置时,所能得到的最优解。F[i][j]就可以直接logn查询,logn把F[i][j]更新到线段树中。

  

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <string>
  5. #include <algorithm>
  6. #include <iostream>
  7.  
  8. using namespace std;
  9.  
  10. const int maxn = ;
  11. int n, a[maxn], b[maxn];
  12. int f[maxn][], cnt[maxn], to[maxn];
  13. int adj[maxn][];
  14. struct Tree
  15. {
  16. int maxv[maxn*];
  17. Tree()
  18. {
  19. memset(maxv, , sizeof(maxv));
  20. }
  21. void pushup(int rt)
  22. {
  23. maxv[rt] = max(maxv[rt<<], maxv[(rt<<)+]);
  24. }
  25. void update(int rt, int l, int r, int p, int d)
  26. {
  27. if (l == r)
  28. {
  29. maxv[rt] = max(maxv[rt], d);
  30. return ;
  31. }
  32. int mid = (l+r)>>;
  33. if (p <= mid)
  34. update(rt<<, l, mid, p, d);
  35. else
  36. update((rt<<)+, mid+, r, p, d);
  37. pushup(rt);
  38. }
  39. int query(int rt, int l, int r, int L, int R)
  40. {
  41. if (L <= l && r <= R)
  42. return maxv[rt];
  43. int mid = (l+r)>>, ret = ;
  44. if (L <= mid)
  45. ret = max(ret, query(rt<<, l, mid, L, R));
  46. if (R > mid)
  47. ret = max(ret, query((rt<<)+, mid+, r, L, R));
  48. return ret;
  49. }
  50. }T;
  51.  
  52. int main()
  53. {
  54. freopen("nocross.in", "r", stdin);
  55. freopen("nocross.out", "w", stdout);
  56. scanf("%d", &n);
  57. for (int i = ; i <= n; ++i)
  58. scanf("%d", &a[i]);
  59. for (int i = ; i <= n; ++i)
  60. scanf("%d", &b[i]), to[b[i]] = i;
  61. for (int i = ; i <= n; ++i)
  62. {
  63. int l = a[i]-, r = a[i]+;
  64. if (l < )
  65. l = ;
  66. if (r > n)
  67. r = n;
  68. cnt[i] = ;
  69. for (int j = l; j <= r; ++j)
  70. adj[i][++cnt[i]] = to[j];
  71. sort(adj[i]+, adj[i]+cnt[i]+);
  72. }
  73. for (int i = ; i <= n; ++i)
  74. {
  75. for (int j = ; j <= cnt[i]; ++j)
  76. if (adj[i][j]- >= )
  77. f[i][j] = T.query(, , n, , adj[i][j]-)+;
  78. else
  79. f[i][j] = ;
  80. for (int j = ; j <= cnt[i]; ++j)
  81. if (adj[i][j]- >= )
  82. T.update(, , n, adj[i][j], f[i][j]);
  83. }
  84. printf("%d\n", T.maxv[]);
  85. return ;
  86. }

  

USACO 2017 FEB Platinum nocross DP的更多相关文章

  1. USACO 2017 FEB Platinum mincross 可持久化线段树

    题意 上下有两个位置分别对应的序列A.B,长度为n,两序列为n的一个排列.当Ai == Bj时,上下会连一条边.你可以选择序列A或者序列B进行旋转任意K步,如 3 4 1 5 2 旋转两步为 5 2 ...

  2. USACO 2017 February Platinum

    第二次参加USACO 本来打算2016-2017全勤的 January的好像忘记打了 听群里有人讨论才想起来铂金组三题很有意思,都是两个排列的交叉对问题 我最后得分889/1000(真的菜) T1.W ...

  3. USACO 2017 January Platinum

    因为之前忘做了,赶紧补上. T1.Promotion Counting 题目大意:给定一个以1为根的N个节点的树(N<=100,000),每个节点有一个权值,对于每个节点求出权值比它大的子孙的个 ...

  4. [USACO 2017 Feb Gold] Tutorial

    Link: 传送门 A: 分层图最短路(其实就是最短路转移时多记录一维的数据 #include <bits/stdc++.h> using namespace std; #define X ...

  5. USACO 2017 FEB Gold visitfj 最短路

    题意 有一幅n*n的方格图,n <= 100,每个点上有一个值.从(1,1)出发,走到(n,n),只能走四联通.每走一步花费t,每走三步需要花费走完三步后到达格子的值.求最小花费的值. 拆点,d ...

  6. [ USACO 2017 FEB ] Why Did the Cow Cross the Road III (Gold)

    \(\\\) \(Description\) 给定长度为\(2N\)的序列,\(1\text ~N\)各出现过\(2\)次,\(i\)第一次出现位置记为\(a_i\),第二次记为\(b_i\),求满足 ...

  7. Usaco 2019 Jan Platinum

    Usaco 2019 Jan Platinum 要不是昨天老师给我们考了这套题,我都不知道usaco还有铂金这么一级. 插播一则新闻:杨神坚持认为铂金比黄金简单,原因竟是:铜 汞 银 铂 金(金属活动 ...

  8. [USACO 2018 Feb Gold] Tutorial

    Link: USACO 2018 Feb Gold 传送门 A: $dp[i][j][k]$表示前$i$个中有$j$个0且末位为$k$的最优解 状态数$O(n^3)$ #include <bit ...

  9. [USACO 2017 Dec Gold] Tutorial

    Link: USACO 2017 Dec Gold 传送门 A: 为了保证复杂度明显是从终结点往回退 结果一开始全在想优化建边$dfs$……其实可以不用建边直接$multiset$找可行边跑$bfs$ ...

随机推荐

  1. photoshop 安装问题

    问题:“安装程序检测到计算机重新启动操作可能处于挂起状态.建议您退出安装程序,重新启动并重试.” 解决: 1.运行 regedit 打开注册表编辑器. 2.依次展开HKEY_LOCAL_MACHINE ...

  2. zookeeper客户端连接报错

    [root@zoo1 zookeeper-3.4.10]# bin/zkCli.sh -server 172.16.1.10:2181 2017-10-27 00:37:59,326 [myid:] ...

  3. PHP缓存加速插件 XCache 、 ZendOpcache 安装

    PHP缓存原理 当客户端请求一个PHP程序时,服务器的PHP引擎会解析该PHP程序,并将其编译为特定的操作码(OperateCode,简称opcode)文件,该文件是PHP代码的一种二进制表示方式.默 ...

  4. PCA算法和SVD

    如果矩阵对某一个向量或某些向量只发生伸缩变换,不对这些向量产生旋转的效果,那么这些向量就称为这个矩阵的特征向量,伸缩的比例就是特征值.这里可以将特征值为负,特征向量旋转180度,也可看成方向不变,伸缩 ...

  5. 使用 redis 减少 秒杀库存 超卖思路

    由于数据库查询的及插入的操作 耗费的实际时间要耗费比redis 要多, 导致 多人查询时库存有,但是实际插入数据库时却超卖 redis 会有效的减少相关的延时,对于并发量相对较少的 可以一用 publ ...

  6. Codeforces 375D - Tree and Queries(dfs序+莫队)

    题目链接:http://codeforces.com/contest/351/problem/D 题目大意:n个数,col[i]对应第i个数的颜色,并给你他们之间的树形关系(以1为根),有m次询问,每 ...

  7. 20165301 2017-2018-2 《Java程序设计》第二周学习总结

    20165301 2017-2018-2 <Java程序设计>第二周学习总结 教材学习内容总结 第二章:基本数据类型与数组 标识符 第一个字符不能是数字 不能是关键字 不能是true.fa ...

  8. cocos2d-x v2.2 IOS工程支持64-bit 遇坑记录

    修改缘由 由于 iPhone 5S的A7 CPU   iPhone 6(A8 CPU)都已经支持64-bit ARM 架构,据说64位处理器跑64代码会提高处理能力?因此二月一新提交appstore应 ...

  9. PHP任意文件上传漏洞CVE-2015-2348浅析

    昨晚安全新闻爆出一个“PHP任意文件上传漏洞”,CVE编号为:CVE-2015-2348. 当时楼主正准备收拾东西回家,看到这个新闻心里一惊:失传江湖多年的0字符截断上传漏洞又重现了?而且还影响这么多 ...

  10. 三十三 StringIO和BytesIO

    StringIO 很多时候,数据读写不一定是文件,也可以在内存中读写. StringIO顾名思义就是在内存中读写str. 要把str写入StringIO,我们需要先创建一个StringIO,然后,像文 ...